Built by Macho Themes.
Special credits: @c0sm1n87
Official home of the Epsilon framework.
License: GNU General Public License v3.0
Issues regarding wp_filesystem on older php versions
.customize-section-back
) should close the .doubled-section-parent
sidebar.doubled-section-parent
panel is opened) should close the sidebar. See how widgets panel handles this.Add a clear input button ( reset to default )
You have several calls to $wp_filesystem->get_contents()
. In all instances, the code doesn't check if the result is false
.
For example, this is from your icon picker class:
$icons = $wp_filesystem->get_contents( $path );
return json_decode( $icons );
And, later in the Underscore template, you loop without checking if there's data to loop through:
<# _.each(data.icons, function(k, v){ #>
At some point, you need to verify that there are icons. You can do this early or late.
Check the following files for issues:
classes/class-epsilon-color-scheme.php
classes/class-epsilon-typography.php
customizer/controls/class-epsilon-control-icon-picker.php
customizer/controls/class-epsilon-control-repeater.php
customizer/controls/class-epsilon-control-section-repeater.php
customizer/controls/class-epsilon-control-typography.php
Looking at Epsilon_Customizer::_get_sanitizer()
in classes/class-epsilon-customizer.php
, I wonder if we can find a better function for sanitizing these things:
case 'epsilon-layouts':
$sanitizer = 'sanitize_text_field';
break;
case 'epsilon-color-scheme':
$sanitizer = 'sanitize_text_field';
break;
sanitize_key
would probably make a bit more sense. sanitize_text_field
allows a few things that sanitize_key
doesn't, such as spaces. And, it seems that these things are more keys/IDs than arbitrary fields. Personally, I'd do a whitelist validation of the existing choices, but sanitize_key
should suffice.
sanitize_text_field
is definitely safe for this. This is just a matter of trying to be improve things a bit.
If the actions are completed in order then everything is OK. If action 6 is complete first and then the other actions, the count will not disappear.
https://github.com/MachoThemes/epsilon-framework/blob/master/assets/js/epsilon.js#L423
If at all possible, the "MedZone Backup Settings" page should not be automatically created when the theme is installed.
The TRT guidelines already don't allow for options to be saved to the DB without explicit user consent (i.e., hitting the "save" button). That rule would really stretch to creating pages too.
The first time you save, you can check if the page exists. If it doesn't, create the page.
We need to download a certain "release" for themes, the .gitmodules file should look smth like this
[submodule "inc/libraries/epsilon-framework"]
path = inc/libraries/epsilon-framework
url = https://github.com/MachoThemes/epsilon-framework/
branch = 1.1.0
where branch is the tag
If the eventual plan is to allow other developers to bundle the framework in their themes, you'll want to provide a filter hook for Epsilon_Framework->path
. Right now, it's set at /inc/libraries
and can't be changed.
On the edit page screen, in addition to the notice, the theme should hide the editor so that the user cannot edit the page content.
You should be able to do this with the following code:
add_action( 'edit_form_after_title', 'epsilon_disable_front_page_editor' );
function epsilon_disable_front_page_editor( $post ) {
if ( get_option( 'page_on_front' ) == $post->ID )
remove_post_type_support( $post->post_type, 'editor' );
}
Of course, change get_option( 'page_on_front' )
to a function for getting your "backup" page ID if that's the route you choose.
You'd only want to hide it in production. Obviously, you'd want to view it during development.
At the current moment, epsilon creates a control even for the blog page.
-> we need to "hide" controls by active callback
-> or integrate it somehow ( maybe allow addition of sections after the blog, e.g. -> adding a newsletter section afterwards or some other specific block )
In Doctors and Testimonials sections, for example, the big blue button doesn't match the rest of the core WP UI. I'd look at what core is doing with the Menus and Widgets sections. You done this with the "Add a Section" button. You should follow through within the individual page section repeating fields.
I'm attaching a couple of screenshots to help describe the other aspect of this. If you could pull this off, it'd be awesome. If not, what you have is good enough.
The first screenshot is showing how I'd like to see items (testimonials in this case) moved to main section. That way, the user doesn't have to click the button to manage all testimonials. Then, the "Add Testimonial" button can simply be to slide out the options for adding a testimonial. And, clicking on an individual testimonial would allow you to manage that single testimonial in the slide out.
I hope that explains it well enough. If not, the screenshots should help. And, this is just an idea from a usability perspective. Consider it low-priority.
cursor: pointer
on hoverWhen storing the page content, you need to go all out. This is what will make a huge difference between me (or another reviewer) seeing this feature as "working with the guidelines" vs. "working around the guidelines".
When formatting the content in the post, format it like you actually care if the user is able to edit it in the future or have it display reasonably if they switch away from your theme.
I'm only going to list some examples. It's up to you to take it all the way.
Currently, this is what it looks like when you have one section after another:
<!-- /Accordion Section -->
<!-- Testimonials Section -->
Simple fix would be:
<!-- /Accordion Section -->
<!-- Testimonials Section -->
It's a small detail, but it matters.
While Gutenberg is not final yet, perhaps it wouldn't hurt to follow in their footsteps with the HTML comments.
This section:
<!-- Testimonials Section -->
Might become:
<!-- epsilon/testimonials -->
Or, something along those lines. I think namespacing like that here would just better prepare you for potential things in the future.
Currently, a testimonial is stored like this:
<!-- Testimonials -->
Testimonial Title
Testimonial Subtitle
I've been using Members on nearly every site I've built over the past 5 years or so, especially if there are multiple users on a site. Members does what it's supposed to do, without any problems.
Now this update comes out - much improved UI, option to assign multiple roles per user, option to group capabilities by posts/pages/media/plugins/etc, and other improvements.
<img src="http://localhost/wp-content/uploads/2017/07/IMG_20170715_170728.jpg" />
<!-- /Testimonials-->
Give me something like:
<!-- Testimonials -->
<h2 class="testimonial-title">Testimonial Title</h2>
<h3 class="testimonial-subtitle">Testimonial Subtitle</h3>
<blockquote>
<p>I've been using Members on nearly every site I've built over the past 5 years or so, especially if there are multiple users on a site. Members does what it's supposed to do, without any problems.</p>
<p>Now this update comes out - much improved UI, option to assign multiple roles per user, option to group capabilities by posts/pages/media/plugins/etc, and other improvements.</p>
</blockquote>
<img src="http://localhost/wp-content/uploads/2017/07/IMG_20170715_170728.jpg" />
<!-- /Testimonials-->
Currently, doctors look like:
<!-- Doctors -->
Dr. Jonathan Doe
Surgeon
<p>Pellentesque dapibus tristique ornare. Quisque vitanimate viverra lorem. animatenean luctus lorem mi, et lobortis turpis porttitor ut. Donec dictum dolor varius metus pellentesque, quis elementum massa varius.</p>
http://facebook.com
http://twitter.com
<!-- /Doctors-->
Instead, go with something like:
<!-- Doctors -->
<h2 class="doctor-name">Dr. Jonathan Doe</h2>
<p class="doctor-specialty">Surgeon</p>
<p>Pellentesque dapibus tristique ornare. Quisque vitanimate viverra lorem. animatenean luctus lorem mi, et lobortis turpis porttitor ut. Donec dictum dolor varius metus pellentesque, quis elementum massa varius.</p>
<ul class="doctor-social">
<li><a href="http://facebook.com">Facebook</a></li>
<li><a href="http://twitter.com">Twitter</a></li>
</ul>
<!-- /Doctors-->
In class-epsilon-framework.php
(119, 138, 156), you need to prefix WPUrls
here:
wp_localize_script( 'epsilon-previewer', 'WPUrls', array(
This variable gets set in the global namespace by WP, so you'll want it prefixed with your framework slug.
When creating repeating content via the customizer, such as testimonials, each testimonial should be stored on a per-page basis. For example:
The problem was when I started customizing Page B, Testimonial X and Y were appearing in the testimonials section as existing testimonials.
I haven't gotten down into the code of this, but each page's customizer content should be stored on a per-page basis.
Like the "front page" when viewed in the admin, I'd like to the other pages edited via the customizer given the same or similar treatment.
At the top of the page, let's get a notice that's something like:
This page contains content created by the customizer. <a href="#">Edit In Customizer →</a>
Then, you need to decide if you're going to allow the user to edit from that screen. If so, your notice should also explain that it will overwrite their customizations. If not, I'd disable the editor on this screen.
He will always use :
16px for font-size
0 for letter-space
18px for line-height
The $autoloader
variable in class-epsilon-autoloader.php
should be prefixed:
$autoloader = new Epsilon_Autoloader();
I wouldn't go as far as saying these things are required. They'd be recommended if you can make them happen (now or in the future). These are what would take your implementation from good to great.
The whole point of the WordPress.org content creation guideline is to not save content as theme mods (or in the wp_options
table at all). However, I have no clue how to accomplish this feature without first saving as an option.
The idea would be that the "settings" would be stored as post content when the user hit "Save and Publish". The settings would never at any point be stored as a theme option.
Which would allow for...
The content that's called on the front end would merely be a wrapper function that parses $post->post_content
.
If you could work out the two things above, you'd be able to create a "customizer page builder" for any page rather than just the front page of the site.
For my final thoughts on the customizer, I wanted to bring up one of my biggest gripes about customizer frameworks.
And, that gripe is with wrapper methods like Epsilon_Customizer::add_control()
, add_field()
, and so on.
To me, this discourage developers from learning the existing customizer code while not adding a lot of value. At best, you're saving a few dozen lines of code in a big theme but still making the code more complex to follow.
I'd rather see the library of awesome controls and such in this framework presented as simply a library to use with $wp_customize
.
Eventually, a developer is going to be limited by the framework wrappers and need to roll with the core WP methods anyway. So, I'd encourage always doing that so that there's not a mismatch of different ways of working with the customizer.
cateodata, nu se initiaza text editorul ( stergi sectiunea Hero, o adaugi la loc <- probabil crede ca e deja initiat )
Under the "Front Page" panel, the only section shown should be "Static Front Page" when the user hasn't yet set a page as a front page. You should use the active_callback
method to show/hide the other sections.
I'm not a huge fan of hiding all those sections though because users might not know they exist. If you can find a way to make them grayed-out/unclickable until a user has chosen a front page, it'll give a clearer path for the user to follow.
That's one reason I'd love to see the core "Static Front Page" section shown at the top as the first section. Choosing a front page is the first and arguably the most important step of the process.
I'd rather you go the front page route, but if sticking with your current method:
You have a rather complicated method of creating a prefixed option name:
$theme = wp_get_theme();
$this->slug = $theme->get( 'TextDomain' );
$this->slug_sanitized = str_replace( '-', '_', $theme->get( 'TextDomain' ) );
$this->hash = $this->calculate_hash();
$this->setting_page = get_option( $this->slug_sanitized . '_backup_settings', false );
It'd be far easier to simply do this:
$this->settings_page = get_option( get_template() . '_backup_settings', false );
Or, use get_stylesheet()
if you want to save based on the active theme (in case a child theme is in use).
Of course, it's entirely possible for the TextDomain
value and get_template()
to be very different. get_template()
is just simpler.
Improve how changes are reflected in the frontend ( from epsilon-previewer.js )
Customizer settings should be saved as "post_meta" on individual pages, creating "sort-of" frontend-customizer-page-builder-like experience.
add_filter ('epsilon_upsell_display', '__return_false');
e.g. Clicking a "title" in the customizer (maybe if you have admin "privileges" - even in the frontend) will allow you to edit it on the spot.
At this point, it may be a bit late to refactor all of your code, but I dislike using the global $wp_customize
object (looking at the Epsilon_Customizer
class at the moment). WP passes the customize object around via its hooks, such as customize_register
. I think it'd be best if your code done the same. Pass the object as a parameter so that you're not having to use the global.
This would also help with the following:
I noticed this in your Epsilon_Customizer
class:
/**
* Theme check fails because there is no "specific" sanitize_callback argument. All fields are sanitized automatically check -> Epsilon_Customizer::_get_sanitizer();
*/
$func_name = 'add_setting';
/**
* Register it
*/
$wp_customize->$func_name(
new $class['class'](
$wp_customize,
$id,
$args
)
);
If you were passing the object as a parameter, you could name it anything. And, you wouldn't get tripped up with that stupid TC check (I've run into the same issue).
Currently, content is saved here reference:
add_action( 'customize_register', array( $this, 'backup_settings' ), 999 );
That means that the page content is never stored until the customizer is reloaded. Instead, use the customize_save_after
hook.
Note that I've successfully tested this in a small test project. Here's some sample code from that to give you an idea of how I handled the save callback:
add_action( 'customize_save_after', array( $this, 'save_page' ) );
public function save_page( $wp_customize ) {
$blocks = array();
$contents = $array_of_setting_names;
foreach ( $contents as $content ) {
$blocks[] = $this->format_text_block( $wp_customize->get_setting( $content )->value() );
}
$output = join( "\n\n", $blocks );
wp_update_post(
array(
'ID' => $this->front_page_id,
'post_content' => $output
)
);
}
The loading of the main stylesheet is being "postponed" and looks glitchy
When creating a front page editor, you already have everything you need. There's no need to create an additional "backup" page.
Let the user choose their front page. Then, get that page ID via get_option( 'page_on_front' )
.
Some of the benefits to this:
draft
status.A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.