Giter VIP home page Giter VIP logo

epsilon-framework's Introduction

Epsilon Framework v1.2.3

Built by Macho Themes.

Special credits: @c0sm1n87

epsilon-framework's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

epsilon-framework's Issues

Don't auto-create backup settings page

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.

Misc JS enhancements

  • Currently, it's possible to expand as many sections as we want. Normal behavior should prevent this and collapse a previously expanded section when trying to expand a new one. See how widgets behave when trying to expand more than one
  • Clicking on the panel's back arrow (.customize-section-back) should close the .doubled-section-parent sidebar
  • Clicking inside the section repeater panel (while the .doubled-section-parent panel is opened) should close the sidebar. See how widgets panel handles this.

Backup page option name

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.

Inplace editing for epsilon fields

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.

Formatting backup page content

When 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.

Spacing between sections

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.

Gutenberg format

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.

Testimonial

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-->

Doctors

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-->

Use the front page, not a backup page

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:

  • You don't have to create the page.
  • You don't have to worry about making sure it stays in draft status.
  • If the user switches themes, the content that they've created is already there on the front page until they choose to do something different.

UI: Adding items within sections

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.

items-ui-001
items-ui-002

Handle blog page

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 )

Text editor issue

cateodata, nu se initiaza text editorul ( stergi sectiunea Hero, o adaugi la loc <- probabil crede ca e deja initiat )

Prefixing: Global JS variable

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.

Typography improvements

  • Small resolution fix ( 1360px breaks layout )
  • Maybe add font variant (smallcaps) option? If so, where can we add the "toggle"

Wrappers for add_control(), add_setting(), etc.

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.

Repeater section improvements

  • Generate unique ID ( so we can navigate from menu as in one page )
  • Calling updatefield, should search for the INDEX in the previewer, remove it and re-add it with the new settings ( partial refresh kinda )

Prefix $autoloader

The $autoloader variable in class-epsilon-autoloader.php should be prefixed:

$autoloader = new Epsilon_Autoloader();

wp filesystem

Issues regarding wp_filesystem on older php versions

Backup content using high-level, Jedi-master skills

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.

Don't save as theme options/mods

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...

Use the page content

The content that's called on the front end would merely be a wrapper function that parses $post->post_content.

Use on any page

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.

Filter framework path

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.

Hide the editor

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.

UX: Front page customizer sections

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.

Mixed-up show/hide icons

image


The "hidden" icon (top right of the notification) is currently highlighted which I believe is wrong.

Save content on ID

Customizer settings should be saved as "post_meta" on individual pages, creating "sort-of" frontend-customizer-page-builder-like experience.

Repeating content is not page specific

When creating repeating content via the customizer, such as testimonials, each testimonial should be stored on a per-page basis. For example:

  • I created Page A and added Testimonial X and Testimonial Y.
  • I created Page B and added Testimonial Z.

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.

Divider/Marker

  • Create a "divider/marker" control param for each epsilon controls -> will help in grouping them in tabs in future updates.
  • We can't edit core controls, so we need to create a custom control for this

Edit page screen in the admin

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 &rarr;</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.

Hook for saving content backup

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
		)
	);
}

Travis CI build

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

Checking filesystem calls

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

Don't rely on global $wp_customize

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).

Sanitizing fields

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.

pre-defined sections/controls

  • Create options automatically
  • Create helping functions to retrieve settings ( e.g. Epsilon_Framework::get_settings('footer') -> that will return an array with all that we need )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.