Enclavely / tailor

Build beautiful page layouts quickly and easily using your favourite WordPress theme.
https://www.tailorwp.com
GNU General Public License v3.0
1.05k stars 102 forks source link

Allow for custom namespaced elements #139

Closed conwaydev closed 7 years ago

conwaydev commented 7 years ago

I don't know if this is the right way to go about this, but we noticed that the 1.8.0 update broke our custom elements and we believe the root of it is because of the explicit model update and the check for tailor:tailor_[element] inside of class-models.php.

There are couple things to note for our usage of Tailor:

  1. We apply the filter add_filter( 'tailor_save_content_as_html', '__return_false' ); in order to make sure that the post_content stores the shortcodes as apposed to the rendered HTML.

  2. We namespace our components ss_[element] (for Sprout Social) which has always worked since we've started to use Tailor. Heres some example code for our plugin:

class-avatar.php

if (class_exists('Tailor_Element') && !class_exists('Ss_Avatar_Element')) {
    class Ss_Avatar_Element extends Tailor_Element {
        protected function register_controls() {
            $this->add_section('general', array(
                'title' => __('General', 'tailor'),
                'priority' => 10,
            ));

            $priority = 0;

            $this->add_setting('modifier');
            $this->add_control('modifier', array(
                'label' => __('Modifiers'),
                'type' => 'select-multi',
                'priority' => $priority += 10,
                'section' => 'general',
                'choices' => array(
                    'default' => __('Default', 'tailor'),
                    '_large' => __('Avatar: Large', 'tailor'),
                ),
            ));
            $this->add_setting('href', array(
                'default' => '//sproutsocial.com/insights/authors/alex-york/'
            ));
            $this->add_control('href', array(
                'label' => __('href'),
                'type' => 'text',
                'priority' => $priority += 10,
                'section' => 'general',
            ));
            $this->add_setting('title', array(
                'default' => 'Alex York'
            ));
            $this->add_control('title', array(
                'label' => __('title'),
                'type' => 'text',
                'priority' => $priority += 10,
                'section' => 'general',
            ));
            $this->add_setting('image', array(
                'default' => 'http://2.gravatar.com/avatar/2696c3a8cc756a3b56b314792675d73b?s=96&d=mm&r=g'
            ));
            $this->add_control('image', array(
                'label' => __('image'),
                'type' => 'text',
                'priority' => $priority += 10,
                'section' => 'general',
            ));
        }
    }
}

if (!function_exists('ss_shortcode_avatar_element')) {
    function ss_shortcode_avatar_element($atts, $content = null, $tag) {
        $avatarString = '<a href="' . $atts['href'] . '" title="' . $atts['title'] . '">';
        $avatarString .= '<img src="' . $atts['image'] . '" alt="' . $atts['title'] . '" />';
        $avatarString .= '</a>';

        return  $avatarString;
    }

    add_shortcode('ss_avatar', 'ss_shortcode_avatar_element');
}

then initializing inside of our tailor-sprout-components.php:

protected function add_actions() {

    // Load element definitions
    add_action( 'tailor_load_elements', array( $this, 'load_elements' ), 20 );

    // Register custom elements
    add_action( 'tailor_register_elements', array( $this, 'register_elements' ), 99 );
}

/**
 * Loads and registers the new Tailor elements and shortcodes.
 */
public function load_elements() {
        require_once $this->plugin_dir() . 'components/class-avatar.php';
}

/**
 * Loads and registers the new Tailor elements and shortcodes.
 *
 * @param $element_manager Tailor_Elements
 */
public function register_elements( $element_manager ) {
    $element_manager->add_element( 'ss_avatar', array(
        'label'             =>  __( 'Avatar' ),
        'description'       =>  __( '' ),
        'badge'             =>  __( 'Sprout' ),
        'type'             =>  'content',
    ) );
}

Without the proposed changes we noticed that the canvas isn't rendering anything:

screen shot 2017-08-14 at 7 53 53 pm

But with the changes we see that it actually runs the generate_models_from_html function:

screen shot 2017-08-14 at 7 55 07 pm


This PR does not break any existing default Tailor components and will continue let us use our namespaced elements, I'd love to be able to update all of our custom elements to be tailor_[our element] but we have 300 pages already built with our existing components and don't want to break those.

Do let me know if this makes sense, or if you need more clarification. We have a very odd way of using Tailor, haha.