Jump to content

Twig?


NextToNothing

Recommended Posts

Hey All,

Coming from a background in developing with Symfony, I've used Twig a lot. Also used templating engines such as smarty and mustache/handlebars - but I believe Twig to be the better of the bunch.

I've seen there was a little discussion about Twig in late 2016 and mid 2017. However, I thought it might be a nice idea to have a constructive discussion about Twig and Blesta?

Even if the end decision was not to use Twig, the discussion might help improve the templating system. Most notably for new-comers to Blesta from competitors or a background like mine (Symfony/Twig or Laravel/Blade).

I'll start off with a few points:

  • Conciseness
    Personally, I believe Twig to be more easy to read and follow the logic, given it's brevity.
    Also, since it uses braces ({}) and not angled brackets (<>), it helps give a contrast between template code and the actual HTML. All this helps readability, which can speed up development and maintainability.
    Arguably, the same could be achieved in PHP via short tags like <? ?> and <?=$var?> - but I believe you may need to enable them in PHP, which is probably why Blesta isn't using them already (given the self-hosted nature).
    <div class="row<?php echo (!$this->Html->ifSet($show_header, true) ? ' login' : '');?>">
        <?php
        if (!empty($active_nav['secondary'])) {
        ?>
            <div class="col-md-3">
                <div class="list-group">
                    <?php
                    foreach ($active_nav['secondary'] as $link => $value) {
                    ?>
                        <a href="<?php $this->Html->_($link);?>" class="list-group-item borderless left-nav <?php echo ($value['active'] ? 'active' : '');?>">
                            <i class="<?php $this->Html->_($value['icon']);?>"></i>
                            <?php
                            $this->Html->_($value['name']);
                            ?>
                        </a>
                    <?php
                    }
                    ?>
                </div>
            </div>
            <div class="col-md-9">
                <div class="row">
                    <?php echo $content;?>
                </div>
            </div>
        <?php
        } else {
            echo $content;
        }
        ?>
    </div>


    versus...
     

    <div class="row{% if not show_header %} login{% endif %}">
        {% if active_nav.secondary is not empty %}
            <div class="col-md-3">
                <div class="list-group">
                    {% for link, value in active_nav.secondary %}
                        <a href="{{ link|e }}" class="list-group-item borderless left-nav {% if value.active %}active{% endif %}">
                            <i class="{{ value.icon|e }}"></i>
                            
                            {{ value.name|e }}
                        </a>
                    {% endif %}
                </div>
            </div>
            <div class="col-md-9">
                <div class="row">
                    {{ content }}
                </div>
            </div>
        {% else %}
            {{ content }}
        {% endif %}
    </div>

    (I didn't test this Twig code, just to confirm)
     

  • Control Structure Syntax
    This kind of comes into conciseness, but is only really for PHP.
    It might be beneficial to use the alternative syntaxes, instead of braces {} in the pdt templates. It would certainly help me get less confused when reading large chunks :P 
    http://php.net/manual/en/control-structures.alternative-syntax.php
     
  • IDEs
    I use PHPStorm, and it has features for Twig, such as better highlighting, auto-completes, etc. With pdt templates being literally PHP, I had to just set them to plain-ol' PHP files - meaning no helpers from the IDE that can speed up development. 
     
  • Inheritance, blocks
    I think this is probably quite a big point, as blocks are more-or-less how the templating engine in Blesta works - except it's all in the core code.
    Again, it helps readability - given that from just the template file, I know all of the templates that are gonna be executed.
    As an example, it can also be useful if someone wanted to change other code on specific pages. In Twig, I'd be able to edit just the one template file - however, with the current system, I'd have to edit core files, which would end up being a pain with upgrades overwriting the files.
    {% extends "structure.html" %}
    
    {% block content %}
        <b>Content of the page...</b>
    {% endblock %}
    opposed to just having a file on it's own with the page content, and having to rely on the core code to define everything else:
    <b>Content of the page...</b>
  • Extensibility
    Obviously, PHP is PHP, and you can do what you like with creating functions etc (however, loading them into the template engine is probably another dicussion).
    Twig is very versatile in the respect.
    For example, phpBB made the switch from their own engine to Twig, and was able to code extensions to Twig to allow all their old templates to run under Twig.
    https://www.phpbb.com/community/viewtopic.php?f=461&t=2424606
     
  • Everything else over on the Twig homepage -https://twig.symfony.com/

 

Obviously, it'll involve a bit of work to move over to Twig, but I feel it would be beneficial in the long run, help new-comers, and more importantly help grow the development of themes for Blesta.

Given Blesta has a template engine orchestrating everything, I might have a little play around with integrating it myself. ?


Hopefully we get a good discussion going on the topic? ;)

 

sidenoteI noticed that templates for plugins can't get overwritten in the app/views/ directory? Thought this was a bit odd, given that most template files have a unique name. So, could we possibly check the app/views/ first before going back to the plugin default. Personally, I wanted to edit a template file in the support_manager plugin but keep all my theme files in one central location (with Git). Unfortunately, I think that I might have to end up with template files here there and everywhere? :S
 

Link to comment
Share on other sites

Proof of concept:

From what I can find, the template rendering is handled inside minPHP (the framework Blesta uses).

With a couple of changes, you can get Twig working along side the existing rendering. Obviously, to optimally utilise twig, you'd have to implement proper caching, fine tune options for Blesta, etc.

This poc allows for use of .pdt files along side .html.twig files, in order to make any transitions between the two a lot easier. (@BlestaStore;))

  1. Add Twig as a composer dependency.
    Note: This is easier said than done if you're not an employee of Phillips Data, Inc. due to autoloading. The easiest way I found was to create a new directory and composer require the files there, then edit lib/init.php to load your autoloader as well.
  2. Edit the following in vendors/minphp/bridge/src/Lib/View.php:
    <?php
    
    use Minphp\Bridge\Initializer;
    
    /**
     * Allows the creation of views.
     */
    class View extends Language
    {
        // ...
    
    
        /**
         * Returns the output of the view
         *
         * @param string $file The file used as our view
         * @param string $view The view directory to use
         * @return string HTML generated by the view
         */
        final public function fetch($file = null, $view = null)
        {
            $this->setView($file, $view);
    
            $base = $this->container->get('minphp.constants')['ROOTWEBDIR']
                . $this->view_path . 'views' . DIRECTORY_SEPARATOR
                . $this->view . DIRECTORY_SEPARATOR;
    
            $fileTwig = $this->file . '.html.twig';
            $fileLegacy = $this->file . $this->view_ext;
    
            if (file_exists($base . $fileTwig)) {
                return $this->fetchTwig($base, $fileTwig);
            }
    
            return $this->fetchLegacy($base . $fileLegacy);
        }
    
        private function fetchTwig($base, $file)
        {
            $twig = new Twig_Environment(
                new Twig_Loader_Filesystem(
                    $base,
                    $base
                ),
                array(
                    'autoescape' => false,
                )
            );
    
            return $twig->render(
                $file,
                array_merge(
                    [
                        'this' => $this,
                    ],
                    $this->vars
                )
            );
        }
    
        private final function fetchLegacy($file)
        {
            if (is_array($this->vars)) {
                extract($this->vars);
            }
    
            if (!file_exists($file)) {
                throw new Exception(sprintf('Files does not exist: %s', $file));
            }
    
            ob_start(); // Start output buffering
    
            include $file; // Include the file
    
            $contents = ob_get_clean(); // Get the contents of the buffer and close buffer.
    
            return $contents; // Return the contents
        }
    
        // ...
    }

     

  3. Done - Twig files will now be rendered ;) 
    Twig will be preferred. So, if you have client_main.pdt and client_main.html.twig, the twig version will be rendered. If no twig version is available, it will load the pdt version :) 

Moving forward from the proof-of-concept, you will be able to recode all the template files to use Twig. Preferably, coding them in Twig will allow the use of {% extends %}, and then the whole code for rendering in Blesta becomes a lot simpler (no need for $structure_view in Controller.php!)

Looking forward to comments :D 

 

Edit: Try out Twig, with this new client_main.html.twig file:


{{ myinfo }}

<div class="col-md-9 right_content">
    {{ message }}

    <script>

      $(document).ready(function() {
        $(".right_content").blestaLoadWidgets({
          fetch_uri: "{{ this.base_uri|e }}main/getwidgets/ {{ client.id|e }}"
        });
      });
    </script>
</div>

;) 

Link to comment
Share on other sites

i love the idea to use twig in blesta, but it should for a long run as mentioned and implemented in processing steps . this will give developers to update their plugins/modules/gateways ... ect

the template idea in blesta is quite simple and easy to understand by basic users as it use flat php syntax .

blesta in some part override the $structure view and the $view for some reason, i love the idea as we have used in some other projects with this feature. so we select and use any view dir we want in a special case . the idea also can apply to twig also without any issues.

Smarty is a good alternative also, and why not a more complete template engine that the actual one.

just to note, the actual template engine is doing the job as it should do :blesta:

Link to comment
Share on other sites

I agree the current way of templating does the job. However, it is a bit cumbersome, and in some cases can be limiting with the the whole "pages expected to be rendered within the structure.pdt file" - opposed to actual inheritance.

When I started coding the template files, it thrown be back a good few years back to the days of procedural PHP code.

Twig is more OO in it's design. It makes heavy use of inheritance and trait-like blocks/includes. It just makes more sense to utilise such features. 

I mean, you could write an entire application in procedural PHP code today, and it'll do the job, yeah - but there are reasons we choose to code in OO with classes etc.

Personally, I think a good metaphor is that; templating (like Twig) is the same to PHP, that a "preprocessor" (like Sass/Less) is to CSS.

You can make your code adhere more to DRY principles, by utilising thing like mix-ins and inheritance. Not to mention all the other useful features such as auto-escaping, etc.

Link to comment
Share on other sites

  • 1 year later...
On 8/23/2019 at 9:48 PM, stacklicense said:

No word on Blesta implementing a templating engine ? twig, smarty or the likes?

Are you having trouble using the existing template system? We are not opposed to something like twig, but changing things now would be involved and the current template system is simple and works well. Why change it now?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...