Twig, the flexible, fast, and secure template language for PHP

Overview

Twig, the flexible, fast, and secure template language for PHP

Twig is a template language for PHP, released under the new BSD license (code and documentation).

Twig uses a syntax similar to the Django and Jinja template languages which inspired the Twig runtime environment.

Sponsors

Blackfire.io

More Information

Read the documentation for more information.

Issues
  • Bump minimum version to PHP 5.6

    Bump minimum version to PHP 5.6

    Twig 2.0 will be released really soon now (hopefully by the end of the year). So, it's time again to reconsider the minimum PHP version we want to support.

    I would like to bump it to PHP 5.6 for the following reasons:

    • PHP 5.5 is not supported anymore (not even security fixes now);

    • the latest Ubuntu LTS is already using PHP 7!

    • #2228 allows to improve performance significantly and having this without the ifstatement makes the optimization more interesting.

    What do you think?

    opened by fabpot 49
  • added namespaced templates support in Twig_Loader_Filesystem

    added namespaced templates support in Twig_Loader_Filesystem

    Everything is explained in the updated documentation.

    Basically, it gives more flexibility when it comes to manage many templates that are not necessarily related (think frontent vs backend for instance, or templates from different Symfony bundles, ...). It is useful if, for each namespace, you need to look for templates in different directories. This implementation would probably be enough to replace the current Symfony bundle template paths, with more flexibility and less restrictions.

    Feedback is more than welcome. One thing I'm not sure about is the # separator between the namespace and the template path. Is it the best choice? We need a character that is not used in filesystem paths, so good candidates are: @, !, %, $, *, ;, ?.

    Some immediate benefits: give the same template flexibility that we have in Symfony to other frameworks using Twig like Silex. Another benefit would be the ability to share template between Symfony and other frameworks like Twig (more on a proof of concept later).

    opened by fabpot 44
  • [1.28] Deprecated warning when using macro which is imported in parent template

    [1.28] Deprecated warning when using macro which is imported in parent template

    base.html.twig:

    {% import "macro.html.twig" as macro %}
    
    {% block content '' %}
    

    child.html.twig:

    {% extends 'base.html.twig' %}
    
    {% block content %}
        {{ macro.foo() }}
    {% endblock %}
    

    Warning:

    Deprecated: Using the dot notation on an instance of __CLASS is deprecated since version 1.28 and won't be supported anymore in 2.0.

    Is this expected behavior? There is no warning, when I import the macro in child.html.twig again.

    Macros 
    opened by gharlan 41
  • added an include function

    added an include function

    opened by fabpot 41
  • Undefined offset: 0

    Undefined offset: 0

    Hello,

    since f2e5f40 I get An exception has been thrown during the rendering of a template ("Notice: Undefined offset: 0"). which makes it impossible to display any template. The problem comes from the modification made in lib/Twig/Profiler/NodeVisitor/Profiler.php.

    I don't have a solution nor an idea as to why it crashes, I hope someone can fix this quickly.

    opened by Soviann 41
  • Let's talk about Twig 2.0

    Let's talk about Twig 2.0

    No big changes, just the removal of deprecated features and things already documented in the docs.

    see #1525 for some discussions.

    opened by fabpot 40
  • [PHP Extension] Bug when the object implements \ArrayAccess

    [PHP Extension] Bug when the object implements \ArrayAccess

    There is a bug when using the PHP extension and trying to access a public property of an object implementing the \ArrayAccess interface.

    Using the following object:

    <?php
    
    class TwigTest implements \ArrayAccess
    {
        public $vars;
        private $data;
    
        public function __construct()
        {
            $this->vars = array('foo' => 1);
            $this->data = array('bar' => 1);
        }
    
        public function offsetExists($offset)
        {
            return array_key_exists($offset, $this->data);
        }
    
        public function offsetGet($offset)
        {
            if (!$this->offsetExists($offset)) {
                throw new \RuntimeException("Offset '$offset' does not exist !");
            }
    
            return $this->data[$offset];
        }
    
        public function offsetSet($offset, $value)
        {
            $this->data[$offset] = $value;
        }
    
        public function offsetUnset($offset)
        {
            unset($this->data[$offset]);
        }
    }
    

    and trying to access the vars property from a template:

    <?php
    // Controller    
        /**
         * @Template
         */
        public function testAction()
        {
            return array(
                'view'      => new TwigTest(),
            );
        }
    
    {# test.html.twig #}
    
    {{ dump(view.vars) }}
    

    The error message is: Twig_Error_Runtime: An exception has been thrown during the rendering of a template ("Offset 'vars' does not exist !")

    It means that the code is using the \ArrayAccess interface to get the value when it should directly access the public property on the object.

    This error is caused by the PHP extension (it does not occur when the extension is not enabled). I have managed to narrow down the root cause to the TWIG_PROPERTY() call in the extension.

    If you look at the body of the function, you'll see calls to TWIG_GET_ARRAY_ELEMENT which should be the root cause of the issue. We should only be returning the value of the property at this place as it is done by the PHP code.

    I don't know the internals of PHP enough in order to come with a proper fix so any help with debugging this would be much appreciated.

    Related issues:

    • symfony/symfony#5064
    • #668
    opened by vicb 37
  • PHP7 support on Twig extension

    PHP7 support on Twig extension

    I saw Twig extension is now tested against PHP7 but compile failed :

    phpize-7.0.0
    ./configure --with-php-config=/usr/bin/php-config-7.0.0 --enable-twig
    make
    

    Leads to :

    make
    /bin/sh /usr/src/build/php/Twig/ext/twig/libtool --mode=compile cc  -I. -I/usr/src/build/php/Twig/ext/twig -DPHP_ATOM_INC -I/usr/src/build/php/Twig/ext/twig/include -I/usr/src/build/php/Twig/ext/twig/main -I/usr/src/build/php/Twig/ext/twig -I/usr/include/php/7.0.0/php -I/usr/include/php/7.0.0/php/main -I/usr/include/php/7.0.0/php/TSRM -I/usr/include/php/7.0.0/php/Zend -I/usr/include/php/7.0.0/php/ext -I/usr/include/php/7.0.0/php/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /usr/src/build/php/Twig/ext/twig/twig.c -o twig.lo
    mkdir .libs
     cc -I. -I/usr/src/build/php/Twig/ext/twig -DPHP_ATOM_INC -I/usr/src/build/php/Twig/ext/twig/include -I/usr/src/build/php/Twig/ext/twig/main -I/usr/src/build/php/Twig/ext/twig -I/usr/include/php/7.0.0/php -I/usr/include/php/7.0.0/php/main -I/usr/include/php/7.0.0/php/TSRM -I/usr/include/php/7.0.0/php/Zend -I/usr/include/php/7.0.0/php/ext -I/usr/include/php/7.0.0/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /usr/src/build/php/Twig/ext/twig/twig.c  -fPIC -DPIC -o .libs/twig.o
    /usr/src/build/php/Twig/ext/twig/twig.c:23:40: error: ext/standard/php_smart_str.h: No such file or directory
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_ARRAY_KEY_EXISTS':
    /usr/src/build/php/Twig/ext/twig/twig.c:100: warning: passing argument 2 of 'zend_hash_exists' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:157: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:100: error: too many arguments to function 'zend_hash_exists'
    /usr/src/build/php/Twig/ext/twig/twig.c:102: error: 'IS_BOOL' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:102: error: (Each undeclared identifier is reported only once
    /usr/src/build/php/Twig/ext/twig/twig.c:102: error: for each function it appears in.)
    /usr/src/build/php/Twig/ext/twig/twig.c:110: warning: passing argument 2 of 'zend_symtable_exists' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:372: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:110: error: too many arguments to function 'zend_symtable_exists'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_INSTANCE_OF_USERLAND':
    /usr/src/build/php/Twig/ext/twig/twig.c:128: warning: passing argument 1 of 'zend_lookup_class' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_execute.h:43: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:128: error: too many arguments to function 'zend_lookup_class'
    /usr/src/build/php/Twig/ext/twig/twig.c:128: warning: comparison between pointer and integer
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_GET_ARRAYOBJECT_ELEMENT':
    /usr/src/build/php/Twig/ext/twig/twig.c:141: warning: passing argument 1 of 'zend_call_method' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_interfaces.h:41: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:141: warning: passing argument 6 of 'zend_call_method' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_interfaces.h:41: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:143: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_ISSET_ARRAYOBJECT_ELEMENT':
    /usr/src/build/php/Twig/ext/twig/twig.c:164: warning: passing argument 1 of 'zend_call_method' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_interfaces.h:41: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:164: warning: passing argument 6 of 'zend_call_method' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_interfaces.h:41: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:166: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:175: error: 'IS_BOOL' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_CALL_USER_FUNC_ARRAY':
    /usr/src/build/php/Twig/ext/twig/twig.c:206: warning: passing argument 2 of 'zend_hash_get_current_data_ex' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:169: note: expected 'HashPosition *' but argument is of type 'void **'
    /usr/src/build/php/Twig/ext/twig/twig.c:206: error: too many arguments to function 'zend_hash_get_current_data_ex'
    /usr/src/build/php/Twig/ext/twig/twig.c:214:36: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c:214: error: 'ZVAL_STRING' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:217: error: incompatible types when assigning to type 'zval' from type 'struct zval *'
    /usr/src/build/php/Twig/ext/twig/twig.c:220: error: 'zend_fcall_info' has no member named 'object_ptr'
    /usr/src/build/php/Twig/ext/twig/twig.c:224: error: 'zend_fcall_info' has no member named 'retval_ptr_ptr'
    /usr/src/build/php/Twig/ext/twig/twig.c:226: warning: assignment from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_CALL_BOOLEAN':
    /usr/src/build/php/Twig/ext/twig/twig.c:248: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_GET_STATIC_PROPERTY':
    /usr/src/build/php/Twig/ext/twig/twig.c:261: warning: assignment makes pointer from integer without a cast
    /usr/src/build/php/Twig/ext/twig/twig.c:263: warning: passing argument 2 of 'zend_std_get_static_property' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_object_handlers.h:165: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:263: error: too many arguments to function 'zend_std_get_static_property'
    /usr/src/build/php/Twig/ext/twig/twig.c:263: warning: assignment from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_GET_ARRAY_ELEMENT_ZVAL':
    /usr/src/build/php/Twig/ext/twig/twig.c:284: warning: passing argument 2 of 'zend_hash_find' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:152: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:284: error: too many arguments to function 'zend_hash_find'
    /usr/src/build/php/Twig/ext/twig/twig.c:287: error: 'IS_BOOL' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:291: error: too many arguments to function 'zend_hash_index_find'
    /usr/src/build/php/Twig/ext/twig/twig.c:295: warning: passing argument 2 of 'zend_symtable_find' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:348: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:295: error: too many arguments to function 'zend_symtable_find'
    /usr/src/build/php/Twig/ext/twig/twig.c:316:42: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_GET_ARRAY_ELEMENT':
    /usr/src/build/php/Twig/ext/twig/twig.c:316: error: 'ZVAL_STRING' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:322: warning: passing argument 2 of 'zend_symtable_find' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:348: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:322: error: too many arguments to function 'zend_symtable_find'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_PROPERTY':
    /usr/src/build/php/Twig/ext/twig/twig.c:334: error: too few arguments to function 'object->value.obj->handlers->read_property'
    /usr/src/build/php/Twig/ext/twig/twig.c:338: error: 'zend_executor_globals' has no member named 'uninitialized_zval_ptr'
    /usr/src/build/php/Twig/ext/twig/twig.c:375:40: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_PROPERTY_CHAR':
    /usr/src/build/php/Twig/ext/twig/twig.c:375: error: 'ZVAL_STRING' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:390:31: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_CALL_S':
    /usr/src/build/php/Twig/ext/twig/twig.c:390: error: 'ZVAL_STRING' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:394:34: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c:397: error: incompatible types when assigning to type 'zval' from type 'struct zval *'
    /usr/src/build/php/Twig/ext/twig/twig.c:400: error: 'zend_fcall_info' has no member named 'object_ptr'
    /usr/src/build/php/Twig/ext/twig/twig.c:404: error: 'zend_fcall_info' has no member named 'retval_ptr_ptr'
    /usr/src/build/php/Twig/ext/twig/twig.c:406: warning: assignment from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c:411: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:415: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_CALL_SB':
    /usr/src/build/php/Twig/ext/twig/twig.c:425: error: 'IS_BOOL' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:428: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:446:34: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_CALL_ZZ':
    /usr/src/build/php/Twig/ext/twig/twig.c:446: error: 'ZVAL_STRING' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:449: error: incompatible types when assigning to type 'zval' from type 'struct zval *'
    /usr/src/build/php/Twig/ext/twig/twig.c:452: error: 'zend_fcall_info' has no member named 'object_ptr'
    /usr/src/build/php/Twig/ext/twig/twig.c:456: error: 'zend_fcall_info' has no member named 'retval_ptr_ptr'
    /usr/src/build/php/Twig/ext/twig/twig.c:458: warning: assignment from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c:468: error: 'IS_BOOL' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:470: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_NEW':
    /usr/src/build/php/Twig/ext/twig/twig.c:485: warning: passing argument 1 of 'zend_lookup_class' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_execute.h:43: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:485: error: too many arguments to function 'zend_lookup_class'
    /usr/src/build/php/Twig/ext/twig/twig.c:485: warning: comparison between pointer and integer
    /usr/src/build/php/Twig/ext/twig/twig.c:489: error: lvalue required as left operand of assignment
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'twig_add_array_key_to_string':
    /usr/src/build/php/Twig/ext/twig/twig.c:506: error: 'smart_str' has no member named 'len'
    /usr/src/build/php/Twig/ext/twig/twig.c:510: error: 'zend_hash_key' has no member named 'nKeyLength'
    /usr/src/build/php/Twig/ext/twig/twig.c:515: error: 'zend_hash_key' has no member named 'arKey'
    /usr/src/build/php/Twig/ext/twig/twig.c:515: error: 'zend_hash_key' has no member named 'nKeyLength'
    /usr/src/build/php/Twig/ext/twig/twig.c:515: warning: passing argument 3 of 'php_addcslashes' from incompatible pointer type
    /usr/include/php/7.0.0/php/ext/standard/php_string.h:127: note: expected 'char *' but argument is of type 'int *'
    /usr/src/build/php/Twig/ext/twig/twig.c:515: error: too many arguments to function 'php_addcslashes'
    /usr/src/build/php/Twig/ext/twig/twig.c:515: warning: assignment from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c:516: warning: assignment makes pointer from integer without a cast
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_IMPLODE_ARRAY_KEYS':
    /usr/src/build/php/Twig/ext/twig/twig.c:528: warning: excess elements in struct initializer
    /usr/src/build/php/Twig/ext/twig/twig.c:528: warning: (near initialization for 'collector')
    /usr/src/build/php/Twig/ext/twig/twig.c:531: warning: passing argument 2 of 'zend_hash_apply_with_arguments' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:132: note: expected 'apply_func_args_t' but argument is of type 'int (*)(void *, int,  struct __va_list_tag *, struct zend_hash_key *)'
    /usr/src/build/php/Twig/ext/twig/twig.c:534: error: 'smart_str' has no member named 'c'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_RUNTIME_ERROR':
    /usr/src/build/php/Twig/ext/twig/twig.c:551: warning: passing argument 1 of 'zend_lookup_class' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_execute.h:43: note: expected 'struct zend_string *' but argument is of type 'char *'
    /usr/src/build/php/Twig/ext/twig/twig.c:551: error: too many arguments to function 'zend_lookup_class'
    /usr/src/build/php/Twig/ext/twig/twig.c:551: warning: comparison between pointer and integer
    /usr/src/build/php/Twig/ext/twig/twig.c:570:69: error: macro "ZVAL_STRINGL" passed 4 arguments, but takes just 3
    /usr/src/build/php/Twig/ext/twig/twig.c:570: error: 'ZVAL_STRINGL' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:571:33: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c:571: error: 'ZVAL_STRING' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:575:79: error: macro "ZVAL_STRINGL" passed 4 arguments, but takes just 3
    /usr/src/build/php/Twig/ext/twig/twig.c:576: warning: passing argument 2 of 'call_user_function' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_API.h:469: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:581: warning: passing argument 2 of 'call_user_function' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_API.h:469: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:581: warning: passing argument 6 of 'call_user_function' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_API.h:469: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:583: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:584: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:585: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:586: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'TWIG_GET_CLASS_NAME':
    /usr/src/build/php/Twig/ext/twig/twig.c:597: error: 'zend_uint' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:597: error: expected ';' before 'class_name_len'
    /usr/src/build/php/Twig/ext/twig/twig.c:603: error: 'class_name_len' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'twig_add_method_to_class':
    /usr/src/build/php/Twig/ext/twig/twig.c:624: warning: passing argument 1 of 'strlen' from incompatible pointer type
    /usr/include/string.h:397: note: expected 'const char *' but argument is of type 'struct zend_string *'
    /usr/src/build/php/Twig/ext/twig/twig.c:625: warning: passing argument 1 of '_estrndup' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_alloc.h:81: note: expected 'const char *' but argument is of type 'struct zend_string *'
    /usr/src/build/php/Twig/ext/twig/twig.c:628: error: too many arguments to function 'add_assoc_stringl_ex'
    /usr/src/build/php/Twig/ext/twig/twig.c:649:116: error: macro "zend_unmangle_property_name" passed 4 arguments, but takes just 3
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'twig_add_property_to_class':
    /usr/src/build/php/Twig/ext/twig/twig.c:649: error: 'zend_unmangle_property_name' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:654:50: error: macro "add_assoc_string" passed 4 arguments, but takes just 3
    /usr/src/build/php/Twig/ext/twig/twig.c:654: error: 'add_assoc_string' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'twig_add_class_to_cache':
    /usr/src/build/php/Twig/ext/twig/twig.c:664: warning: assignment makes pointer from integer without a cast
    /usr/src/build/php/Twig/ext/twig/twig.c:673: warning: passing argument 2 of 'zend_hash_apply_with_arguments' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:132: note: expected 'apply_func_args_t' but argument is of type 'int (*)(void *, int,  struct __va_list_tag *, struct zend_hash_key *)'
    /usr/src/build/php/Twig/ext/twig/twig.c:674: warning: passing argument 2 of 'zend_hash_apply_with_arguments' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_hash.h:132: note: expected 'apply_func_args_t' but argument is of type 'int (*)(void *, int,  struct __va_list_tag *, struct zend_hash_key *)'
    /usr/src/build/php/Twig/ext/twig/twig.c: In function 'zif_twig_template_get_attributes':
    /usr/src/build/php/Twig/ext/twig/twig.c:752: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:831: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:872: warning: passing argument 1 of 'zval_get_type' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_types.h:312: note: expected 'const struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:872: warning: initialization from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c:872: warning: passing argument 1 of 'zval_get_type' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_types.h:312: note: expected 'const struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:872: warning: passing argument 1 of '_convert_to_string' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_operators.h:242: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:876: warning: passing argument 1 of 'zval_get_type' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_types.h:312: note: expected 'const struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:876: warning: initialization from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c:876: warning: passing argument 1 of 'zval_get_type' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_types.h:312: note: expected 'const struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:876: warning: passing argument 1 of '_convert_to_string' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_operators.h:242: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:881: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:1032:33: error: macro "ZVAL_STRING" passed 3 arguments, but takes just 2
    /usr/src/build/php/Twig/ext/twig/twig.c:1032: error: 'ZVAL_STRING' undeclared (first use in this function)
    /usr/src/build/php/Twig/ext/twig/twig.c:1036: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:1056: warning: passing argument 1 of 'TWIG_INSTANCE_OF' from incompatible pointer type
    /usr/src/build/php/Twig/ext/twig/twig.c:114: note: expected 'struct zval *' but argument is of type 'struct zend_object *'
    /usr/src/build/php/Twig/ext/twig/twig.c:1086: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:1088: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    /usr/src/build/php/Twig/ext/twig/twig.c:1096: warning: passing argument 1 of '_zval_ptr_dtor' from incompatible pointer type
    /usr/include/php/7.0.0/php/Zend/zend_variables.h:111: note: expected 'struct zval *' but argument is of type 'struct zval **'
    make: *** [twig.lo] Error 1
    
    opened by odoucet 35
  • added the inline tag

    added the inline tag

    At Sensio, we manage websites with many mostly-static pages that share almost the same structure (with different content of course), but with some subtle differences. After trying many different possibilities (external templates, inheritance, macros, and some ugly ones that I won't even tell you about ;)) to structure our templates, we came to the conclusion that we needed a new concept.

    This new concept is implemented via a new tag, inline, which I want to include in Twig 1.8 (not for the upcoming 1.7 which is due this week). But before merging this code into master, I want to gather some feedback from the community. One of my questions being: Will you use this new possibility?

    I won't tell you more here as the tag is fully documented in the diff.

    opened by fabpot 34
  • Adding new operators/tests for strings comparison operations?

    Adding new operators/tests for strings comparison operations?

    In a CSS selector, you can easily check if a value start with/ends with/contains something:

    [att ^= val] – the “begins with” selector
    [att $= val] – the “ends with” selector
    [att *= val] – the “contains” selector
    

    In the new Symfony ExpressionLanguage component, there is also two operators (based on Perl) to check if a value matches something:

    attr =~ /regex/  {# regex #}
    attr !~ /regex/  {# not regex #}
    

    As you can see, the = sign is not at the same place in both examples.

    Another way to provide the same feature would be to add tests instead of operators:

    attr is startingwith(val)
    attr is endingwith(val)
    attr is containing(val)
    attr is matching(regex)
    
    attr is not startingwith(val)
    attr is not endingwith(val)
    attr is not containing(val)
    attr is not matching(regex)
    

    So, here are my questions:

    • Any interest in having this feature in Twig Core extension? or in a new extension in core? or in a new extension in Twig-extensions? or is that just too much?
    • Would it be better to have the feature implemented as operators (to be consistent with CSS selectors) or tests (probably easier to read/understand)?

    Note: If we were to implement this feature in Twig as tests, we would replace the Perl regex style operators in the Symfony component with the matching test instead.

    Thoughts?

    opened by fabpot 33
  • Using PHP 7.4 the variable inside the html tag is joining with the previous value.

    Using PHP 7.4 the variable inside the html tag is joining with the previous value.

    Code

    <div class="main-row {{ rows.class }}">
            <div class="container">
                <div class="row">
                </div>
            </div>
      </div>
    

    {{ rows.class }} = full-width

    Result

    <div class="main-rowfull-width">
            <div class="container">
                <div class="row">
                </div>
            </div>
      </div>
    

    After rendering, the engine does not respect the space between classes and joins the 2 values.

    This error I saw happen in PHP 7.4, when switching to PHP with a version lower than 7.4, it worked fine.

    opened by brennosacramento 3
  • Use faster hash algorithm (xxh128) on PHP 8.1+

    Use faster hash algorithm (xxh128) on PHP 8.1+

    Twig uses the hash function at runtime to convert template paths class names, each time a template is loaded. In a large project with a high granularity of templates (hundreds of include per page), this can become the most time consuming function as reported by Blackfire:

    To optimise this use-case, PHP 8.1 supports the xxHash hash algorithms. xxh128 is 60x faster that sha256 according to the benchmarks, and guarantee a very low risk of collision.

    I'm not able to test with PHP 8.1 for now. Before going further I would like to validate performance impact on a large list of file names.

    opened by GromNaN 1
  • Overwrite twig templates in test environment

    Overwrite twig templates in test environment

    Hello,

    I want to overwrite my base template in test environment because I want only test the content of the templates which extend the base template. Therefore in the test environment I want to overwrite the original base template with an empty base template. Is this somehow possible?

    opened by dsmanyp 0
  • LeagueMarkdown converter is explicitly requiring CommonMarkConverter

    LeagueMarkdown converter is explicitly requiring CommonMarkConverter

    League CommonMark: v1.6.6 Twig Markdown-Extra: v3.3.3 Twig: v3.3.3

    The LeagueMarkdown constructor is requiring the $converter parameter to explicitly be an instance of CommonMarkConverter, however with League CommonMark v1.6, the converter looks to have been split into two different instance types:

    1. MarkdownConverter
    2. CommonMarkConverter which extends MarkdownConverter

    For our usage, we're needing to pass-in the $environment to the converter (GitHub flavor with some other slight modifications) So, with v1.6, we can't use CommonMarkConverter since it triggers a deprecation error:

    Passing an $environment into the "League\CommonMark\CommonMarkConverter" constructor is deprecated in 1.6 and will not be supported in 2.0; use MarkdownConverter instead. See https://commonmark.thephpleague.com/2.0/upgrading/consumers/#commonmarkconverter-and-githubflavoredmarkdownconverter-constructors for more details.

    Would it be possible to change the constructor for LeagueMarkdown to only require MarkdownConverter or maybe even just the ConverterInterface?

    opened by trickeyone 1
  • Documentation Website's version alert should link to different version, same topic

    Documentation Website's version alert should link to different version, same topic

    Issue Looking up documentation for twig's include statement, & clicking the alert message "... Switch to the documentation for Twig 1.x, 2.x" link takes the user away from the topic to the documentation root. This happens on all documentation pages.

    Expected When browsing a topic, and offered a link to switch to another version, one expects to be kept on topic where possible.

    Actual All links point to their version's documentation root

    Supporting info This alert is present at the top of all twig.symfony.com/doc documentation pages:

    You are reading the documentation for Twig 3.x. Switch to the documentation for Twig 1.x. 2.x.

    The "switch to" links offered for each version, always point to their version's documentation root:

    • 1.x - https://twig.symfony.com/doc/1.x/
    • 2.x - https://twig.symfony.com/doc/2.x/

    Many like pages exist between versions

    • Extending Twig documentation -- https://twig.symfony.com/doc/1.x/advanced.html -- https://twig.symfony.com/doc/3.x/advanced.html
    • Include statement documentation -- https://twig.symfony.com/doc/2.x/tags/include.html -- https://twig.symfony.com/doc/3.x/tags/include.html
    opened by sheanhoxie 0
  • [BUG] Extension::spaceless: Algorithm removes spaces in the text and causes the meaning to be broken.

    [BUG] Extension::spaceless: Algorithm removes spaces in the text and causes the meaning to be broken.

    The current algorithm causes the meaning of a sentence to be broken because it concatenates multiple tags together, which can be, for example, a link and a formatting tag.

    In case of template:

    {% block content %}
    {% apply spaceless %}
    <p>
        Open <a href="{{ url }}">Google</a> <strong>for more</strong> info.
    </p>
    {% endapply %}
    {% endblock %}
    

    Current output is:

    <p>
        Open <a href="https://google.cz">Google</a><strong>for more</strong> info.
    </p>
    

    But expected output must be:

    <p>
        Open <a href="https://google.cz">Google</a> <strong>for more</strong> info.
    </p>
    

    Snímek obrazovky 2021-10-14 v 15 31 06

    I think more better algorithm should be inspired from Latte engine: https://github.com/nette/latte/blob/53e5da9aa2ec20e6e7e4149448e5d0ad2af282ba/src/Latte/Runtime/Filters.php#L309

    Possible solution

    The algorithm could replace spaces for some tag types with a single separate space, not necessarily remove everything. Formatting tags can be like p, a, strong, b, i, u, ...

    Thanks.

    Rel #3574

    opened by janbarasek 0
  • Feature request: make filter argument optional

    Feature request: make filter argument optional

    Feature request: Make the argument optional for the filter filter.

    Instead of doing this:

    {{ ['123 Main St', null, 'New York', 'NY', '10001']|filter(a => a)|join(', ') }}
    

    it would be great if we could just do this:

    {{ ['123 Main St', null, 'New York', 'NY', '10001']|filter|join(', ') }}
    

    This would match the behavior of the array_filter() function in PHP.

    opened by thsmrtone1 0
  • [RFC] Anonymous blocks

    [RFC] Anonymous blocks

    This proposal seeks to support anonymous blocks: blocks without a name argument. That is, {% block %} (without a name) would be a valid block tag. Consider the following simple and contrived example with named blocks.

    {# button_group.twig #}
    <div class="button-group">
        {% block buttons %}{% endblock %}
    </div>
    
    {# my_template.twig #}
    {% embed 'button_group.twig' %}
        {% block buttons %}
            <div class="button">Button 1</a>
            <div class="button">Button 2</a>
            <div class="button">Button 3</a>
        {% endblock %}
    {% endembed %}
    

    In this example we only declare a single block, so the name of the block isn't needed to distinguish it from other blocks. In any case, the anonymous block can be thought of as a block that has a name but whose name is empty. As such, is would be invalid to specify two anonymous blocks since they would share the same (empty) name. However, applying the anonymous block in this case can be used to simplify both templates as follows.

    {# button_group.twig #}
    <div class="button-group">
        {% block %}{% endblock %}
    </div>
    
    {# my_template.twig #}
    {% embed 'button_group.twig' %}
        <div class="button">Button 1</a>
        <div class="button">Button 2</a>
        <div class="button">Button 3</a>
    {% endembed %}
    

    Eliminating the name made a small difference to our button_group.twig template, but we were able to eliminate the entire block tag pair from my_template.twig and reduce indentation by one level. This would be possible under this proposal because of the following additional change: normally, templates that embed or extend can only declare block tags, but under this proposal it would also support and collect content outside any block declaration and treat it as content for the anonymous block.

    It would still be possible to include named blocks as normal as in the following example that mixes named and anonymous blocks.

    {# button_group.twig #}
    {% if block('title') is defined %}
        <h1>{% block title %}{% endblock %}</h1>
    {% endif %}
    <div class="button-group">
        {% block %}{% endblock %}
    </div>
    
    {# my_template.twig #}
    {% embed 'button_group.twig' %}
        {% block title %}My buttons{% endblock %}
        <div class="button">Button 1</a>
        <div class="button">Button 2</a>
        <div class="button">Button 3</a>
    {% endembed %}
    
    opened by Bilge 0
  • ext-intl's use of IntlDateFormatter prototype has several bugs

    ext-intl's use of IntlDateFormatter prototype has several bugs

    \Twig\Extra\Intl\IntlExtension's constructor takes an optional IntlDateFormatter prototype. That works great for settings various defaults (dateType, timeType, pattern), but it doesn't enable automatic timezone conversion.

    IntlDateFormatter

    Consider this plain PHP example:

    echo (new IntlDateFormatter(
    	'nl_NL',
    	IntlDateFormatter::MEDIUM, IntlDateFormatter::MEDIUM,
    	new DateTimeZone('Europe/Amsterdam')
    ))->format(new DateTime()) . "\n";
    

    This automatically formats the UTC datetime using Amsterdam time. Neat!

    twig/intl-extra

    new IntlExtension(new IntlDateFormatter(/* ... */)) however doesn't apply the timezone, unfortunately.

    Why not?

    IntlExtension::formatDateTime lets \twig_date_converter create a DateTime using CoreExtension::getTimezone() and passes its timezone to IntlExtension::createDateFormatter() - even when no timezone was passed to formatDateTime.

    Passing in an explicit $timezone to createDateFormatter() makes the method use that value instead of $this->dateFormatterPrototype->getTimeZone(). (which is actually broken - see https://github.com/twigphp/intl-extra/pull/6 ;p).

    Quirky workaround

    Maybe users are supposed to

    $twig->getExtension(CoreExtension::class)->setTimeZone('Europe/Amsterdam');
    

    In that case though, date strings are not converted at all:

    {{ '2021-09-30 13:37'|format_datetime() }} {# still 13:37 #}
    

    DateTime objects are converted.

    opened by drjayvee 11
  • Make function existence deterministic in Twig `AppExtension`

    Make function existence deterministic in Twig `AppExtension`

    'm just forwarding what @ondrejmirtes told me at https://github.com/phpstan/phpstan/issues/5640#issuecomment-921238545:

    Calling twig_date_format_filter() in App\Twig\AppExtension sometimes leads to phpstan reporting

    Function twig_date_format_filter not found

    ... and sometimes it doesn't ;-)

    @ondrejmirtes at https://github.com/symfony/symfony/issues/43067#issuecomment-921596507:

    This can usually be solved by separating functions into their own files and putting those files into Composer's autoload.files section.

    opened by ThomasLandauer 0
PHP Template Attribute Language — template engine for XSS-proof well-formed XHTML and HTML5 pages

PHPTAL - Template Attribute Language for PHP Requirements If you want to use the builtin internationalisation system (I18N), the php-gettext extension

PHPTAL 165 Nov 17, 2021
Multi target HAML (HAML for PHP, Twig, )

Multi target HAML MtHaml is a PHP implementation of the HAML language which can target multiple languages. Currently supported targets are PHP and Twi

Arnaud Le Blanc 362 Aug 5, 2021
A complete and fully-functional implementation of the Jade template language for PHP

Tale Jade for PHP Finally a fully-functional, complete and clean port of the Jade language to PHP — Abraham Lincoln The Tale Jade Template Engine brin

Talesoft 93 May 4, 2021
Provides TemplateView and TwoStepView using PHP as the templating language, with support for partials, sections, and helpers.

Aura View This package provides an implementation of the TemplateView and TwoStepView patterns using PHP itself as the templating language. It support

Aura for PHP 81 Nov 16, 2021
The free-to-use template for your Imagehost-website made with PHP, HTML and CSS!

The free-to-use template for your Imagehost-website made with PHP, HTML and CSS! Some information before we start This repo is only code related, to a

Ilian 5 Nov 3, 2021
The free-to-use template for your Imagehost-website made with PHP, HTML and CSS!

The free-to-use template for your Imagehost-website made with PHP, HTML and CSS! Some information before we start This repo is only code related, to a

Ilian 5 Nov 3, 2021
⚡️ Simple and fastly template engine for PHP

EasyTpl ⚡️ Simple and fastly template engine for PHP Features It's simple, lightweight and fastly. No learning costs, syntax like PHP template It is s

PHPPkg 9 Nov 26, 2021
PHP template engine for native PHP templates

FOIL PHP template engine, for PHP templates. Foil brings all the flexibility and power of modern template engines to native PHP templates. Write simpl

Foil PHP 163 Nov 20, 2021
A SilverStripe Module with template methods to quickly make use of FocusPoint, LazySizes, and Object-fit

LazyFocusFit A SilverStripe module with template methods to quickly make use of FocusPoint, LazySizes and object-fit. Requirements PHP FocusPoint JS/C

Evans Hunt 8 Oct 12, 2021
Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.

Smarty 3 template engine smarty.net Documentation For documentation see www.smarty.net/docs/en/ Requirements Smarty can be run with PHP 5.2 to PHP 7.4

Smarty PHP Template Engine 1.9k Nov 23, 2021
Native PHP template system

Plates Plates is a native PHP template system that's fast, easy to use and easy to extend. It's inspired by the excellent Twig template engine and str

The League of Extraordinary Packages 1.3k Nov 19, 2021
View template engine of PHP extracted from Laravel

Blade 【简体中文】 This is a view templating engine which is extracted from Laravel. It's independent without relying on Laravel's Container or any others.

刘小乐 145 Aug 13, 2021
A ready-to-use Model View Controller template in PHP

PHP-MVC-Template A ready-to-use Model View Controller template in PHP Use this repo as a template! (Or clone it) Start to configure your MVC file Afte

Loule | Louis 6 Nov 19, 2021
Provides a GitHub repository template for a PHP package, using GitHub actions.

php-package-template Installation ?? This is a great place for showing how to install the package, see below: Run $ composer require ergebnis/php-pack

null 260 Nov 24, 2021
A lightweight template parser used by PyroCMS.

Lex Lex is a lightweight template parser. Lex is released under the MIT License and is Copyrighted 2011 - 2014 PyroCMS Team. Change Log 2.3.2 Convert

PyroCMS 103 Nov 15, 2021
Laravel package template

REPLACE Simple and flexible package template. Usage Replace all occurances of REPLACE (case sensitive) with the name of the package namespace. E.g. th

ARCHTECH 47 Nov 24, 2021
The Templating component provides all the tools needed to build any kind of template system.

Templating Component The Templating component provides all the tools needed to build any kind of template system. It provides an infrastructure to loa

Symfony 982 Nov 23, 2021
Document templates Laravel package is intended for creating/managing user editable document template

Document Templates Introduction Document templates Laravel package is intended for creating/managing user editable document templates, with ability to

42coders 99 Nov 14, 2021
Astroid Framework - Powerful Joomla Template Framework

Powerful framework for designers and developers to create responsive, fast & robust Joomla based websites and templates.

TemPlaza 9 Nov 23, 2021