0
votes

I'm creating a plugin that is directly correlated with a theme I'm developing wich is using Timber. My plugin could render some built in templates (when I call a shortcode the plugin reply with the correct teplate); Those templates are, for now, PHP files. I would use Timber to render those files.

Unfortunatly Issue #261 is still open. And I have no idea on how I can obtain the expected behaviour on the current timber codebase.

Expected behaviour:

  • Register my plugin path for views after the theme path.
  • When a view is called, Timber first check on theme directory, than on the plugin one.

How can I obtain this? Right now I have tested with the templates on my theme and I simply call Timber.render(); but I don't have the local path included.

Standard PHP plugin code:

// On plugin load
add_shortcode('render_social_icons', array($this, 'render_social_icons'));

public function render_social_icons($atts, $content)
    {
        $atts = shortcode_atts(array(
            'class' => '',
            'el-class' => '',
            'link-class' => '',
            'icon-class' => '',
            'size' => '',
        ), $atts);

        ob_start();
        ?>

        <ul class="social-icons shortcode <?php echo $atts['class']; ?>">
            <?php
            $socials = my_socials_links();
            foreach ($socials as $social) :?>
                <?php
                $id = $social['id'];
                $title = $social['name'];
                $baseurl = $social['baseurl'];
                $icon = $social['icon'];

                $social_data = get_theme_mod($id);
                if (!empty($social_data)) :?>
                    <li class="<?php echo $id; ?> <?php echo $atts['el-class']; ?>">
                        <a target="_blank" title="<?php echo $title; ?>" href="<?php printf($baseurl, $social_data); ?>"
                           class="<?php echo $atts['link-class']; ?>">
                            <i class="<?php echo $icon; ?> <?php echo $atts['icon-class']; ?> <?php echo $atts['size']; ?>"></i>
                        </a>
                    </li>
                <?php endif; ?>
            <?php endforeach; ?>
        </ul>

        <?php
        return ob_get_clean();
    }

Converted function for Timber (still a plugin file):

// On plugin load
add_shortcode('render_social_icons', array($this, 'render_social_icons'));

public function render_social_icons($atts, $content)
    {

        $atts = shortcode_atts(array(
            'class' => '',
            'el-class' => '',
            'link-class' => '',
            'icon-class' => '',
            'size' => '',
        ), $atts);

        return Timber.compile('shortcodes/social.twig', array(atts, my_socials_links());
    }

The shortcodes/social.twig is inside the current theme folder, I would like to load this twig template file from the plugin foder.

1
Hello! Thanks for posting your question! I would like to help, and I have some thoughts on what you might need, but your question does not include enough detail to reproduce or diagnose your problem. Please check out the guidelines for posting questions at stackoverflow.com/help/how-to-ask. Hopefully I will be able to help you out with more information! - Jesse
I have added more details and a code example. - hitech95
Thanks, that's much more clear! One more question: you say that the twig file is inside the theme folder and that you "would like to load this file from the plugin folder." Does "this file" refer to the PHP file where this function is located, i.e. you want to keep the twig file in the theme while moving your shortcode definition to a plugin? Or does it refer to the twig file, i.e. you want both the shortcode definition and the twig file to be in the plugin folder? - Jesse
Yes the twig file is inside the theme forlder, due to the fact that I have no idea on how I can register the plugin directory as a valid path for Timber. I have updated the description again with more clear info. The PHP files are from my plugin, the twig files are currentry on my Theme I would move them into the plugin folder. If a theme also contain the same file it should override the one provided by the plugin. - hitech95

1 Answers

1
votes

Timber does not require you to register a twig file in order to use it with Timber::compile. You just need to provide the full path to the file as your first argument. To do that in a plugin, you will need to get the plugin directory path using plugin_dir_path(). To use your example code, you would do something like the following.

public function render_social_icons($atts, $content) {
  $plugin_path = plugin_dir_path( __FILE__ );
  $atts = shortcode_atts(array(
          'class' => '',
          'el-class' => '',
          'link-class' => '',
          'icon-class' => '',
          'size' => '',
        ), $atts);

   return Timber::compile($plugin_dir_path . '/twig/social.twig', $atts);
}

The cool thing about Timber::compile is that you can pass an array of paths, and Timber will use the first file that it finds. That means you can allow a theme to override the social.twig file location with a file in the registered Timber paths. For example, you could change the last line to:

return Timber::compile(array('social-shortcode-custom.twig', $plugin_dir_path . '/twig/social.twig'), $atts);

Then Timber would pass the variables to a file called social-shortcode-custom.twig in the registered Timber locations if it exists, and fall back to the file located in the plugin if not.

I'm not sure if this is affecting things or not, but I don't recognize the syntax you are using for the compile function. I have always seen and used the static method Timber::compile(), but you are using Timber.compile(). Timber is rapidly updating lately, so maybe you've seen something that I missed?