Everything you need to know about twig. Installing and getting started with Twig

Today there are a large number of ways to output to an html page. More and more often, web developers use so-called template engines for these purposes. Today we will look at a small example of using the Twig template engine.

Features of Twig

  • phenomenally fast speed (compared to other template engines)
  • compiling templates into well-optimized PHP code
  • using “inheritance” (you can define a base and child templates)
  • allows you to create and use macros

Installation

There are many ways to install Twig. The simplest and fastest is to download the component from GitHub, after which the archive must be unpacked and the lib directory transferred to the folder with our project.

Project structure

Well, now let's get down to business and look at the structure of our small project:

  • compilation_cache
  • lib
    • Twig
  • templates
    • base.html
    • books.html
  • index.php

All functionality related to connecting and configuring Twig is contained in the file index.php.

We will store template files in the templates folder. In our case, there are 2 of these files: base.html with basic html code and books.html with a list of books.

In the catalog compilation_cache PHP files created by Twig for work will be placed.

Connection and basic configuration of Twig

So, the first thing we need to do is connect Twig:

Require_once "lib/Twig/Autoloader.php"; Twig_Autoloader::register();

After that, we tell the template engine where we store the template files. We pass the path to the directory as an argument templates:

$loader = new Twig_Loader_Filesystem("templates");

Then we create a template engine object and specify a few more options:

$twig = new Twig_Environment($loader, array("cache" => "compilation_cache", "auto_reload" => true));

Parameter cache pass the path to the directory compilation_cache. Activate the option auto_reload so that when the page is refreshed, Twig re-processes the templates and we see the changes. If this is not done, the template engine will simply cache the pages. When work on the project is completed, this option can be removed so that your pages are cached and loaded even faster.

Data

To implement our small example, let’s take a list of books and form an array of the form key - value:

$books = array(array("number" => "Book 1", "title" => "Harry Potter and the Philosopher's Stone", "date" => "06/30/1997"), array("number" => " Book 2", "title" => "Harry Potter and the Chamber of Secrets", "date" => "07/2/1998", array("number" => "Book 3", "title" => "Harry Potter and Prisoner of Azkaban", "date" => "07/8/1999"), array("number" => "Book 4", "title" => "Harry Potter and the Goblet of Fire", "date" => "07/8/2000 "), array("number" => "Book 5", "title" => "Harry Potter and the Order of the Phoenix", "date" => "07/21/2003"), array("number" => "Book 6 ", "title" => "Harry Potter and the Half-Blood Prince", "date" => "07/16/2005", array("number" => "Book 7", "title" => "Harry Potter and the Gifts Deaths", "date" => "07/21/2007"));

File upload and data transfer

In order to pass data to some template and output the html result, we need to use the method render(); As the first argument, we pass the name of the template file that we will output. The second is an array of the form key - value. In the future, using the given keys, we will access our data in the templates themselves.

Echo $twig->render("books.html", array("books" => $books));

index.php

General view of the index.php file

Require_once "lib/Twig/Autoloader.php"; Twig_Autoloader::register(); $loader = new Twig_Loader_Filesystem("templates"); $twig = new Twig_Environment($loader, array("cache" => "compilation_cache", "auto_reload" => true)); $books = array(array("number" => "Book 1", "title" => "Harry Potter and the Philosopher's Stone", "date" => "06/30/1997"), array("number" => " Book 2", "title" => "Harry Potter and the Chamber of Secrets", "date" => "07/2/1998", array("number" => "Book 3", "title" => "Harry Potter and Prisoner of Azkaban", "date" => "07/8/1999"), array("number" => "Book 4", "title" => "Harry Potter and the Goblet of Fire", "date" => "07/8/2000 "), array("number" => "Book 5", "title" => "Harry Potter and the Order of the Phoenix", "date" => "07/21/2003"), array("number" => "Book 6 ", "title" => "Harry Potter and the Half-Blood Prince", "date" => "07/16/2005", array("number" => "Book 7", "title" => "Harry Potter and the Gifts Deaths", "date" => "07/21/2007")); echo $twig->render("books.html", array("books" => $books));

Setting up a basic template

The basic template is a regular HTML document with special inserts:

(% block title %)(% endblock %)

(% block content %) (% endblock %)

In our main template we write 2 blocks: title and content. We choose the names of the blocks ourselves.

Subsequently, we will introduce information specific to child pages into these common blocks.

Setting up a book output template

First, in the child template, we need to specify the parent template:

(% block title %)Harry Potter series(% endblock %)

Then, we write the content, which will be embedded in a block called content in the base template:

(% block content %)

Harry Potter series of novels

(% for books in books %)
((book.number)). "((book.title))"- ((book.date))
(%endfor%)
(%endblock%)

Right there in the for loop (Twig for) we go through all the books that were transferred to this template using the entry $twig->render("books.html", array("books" => $books)); and to retrieve values, we access the array elements by key: ((book.number)), ((book.title)), and so on.

Thus, after the $twig->render("books.html", array("books" => $books)) method is triggered, Twig will load the books.html template and generate the html content. It will then recognize that books.html is a child template of base.html and place the generated content into the base template. After all this, Twig will return us a full html page.

Bottom line

You can see an example of how this script works in the demo or download an archive with a ready-made example.

We are waiting for your impressions in the comments. If you are interested in this topic, then in the future we will continue to talk about the Twig template engine.

, | |

What is Twig?

Download the Composer installer to the application root folder (twig):

cd /var/www/twig
curl -s http://getcomposer.org/installer | php

This will download a file called composer.phar, which is the Composer executable. Then create a file called composer.json:

nano composer.json

And add the following code into it:

{
"require": (
"twig/twig": "1.*"
}
}

This code will make the application dependent on the Twig template engine. Now let's use the composer command to install the dependencies:

php composer.phar install

The Twig files are now downloaded to the vendor/Twig folder. If you add other dependencies, they will also be installed in the vendor folder.

Now you need to “connect” this file to the application. Again, you can use Composer's autoloader feature to load all installed dependencies. Open the app.php file:

nano app/app.php

Delete all its contents and add this line:

This line will load the Composer autoloader, which in turn will load Twig. If Twig was installed using another method, you will need the Twig autoloader:

require_once "/path/to/lib/Twig/Autoloader.php";
Twig_Autoloader::register();

This is not necessary when using Composer.

Under the require command, you need to place the Twig template file and set the variable that you want to display on the page. Paste the following code:



render("page.html", array("text" => "Hello world!")); ?>

First, it will create a loader object that is passed the path to the folder containing the template files (the currently empty views folder was created earlier). Additionally, this code will also create an environment object that stores the configuration. Finally, the render line of the environment object loads the template file given as the first argument and renders it given the variables given as the second argument. Now you need to create a page.html file in which you can add variables containing the text you want to display.

nano views/page.html

Enter the following into it:

((text))

If you save this file and restart the app.php file in the browser, the text taken in the H1 tags will be displayed on the page. Now that you've created this file, you can experiment with it. Variables set through the render function can now be enclosed in curly braces.

For the sake of experimentation, you can pass several variables to the template, use them in control structures, process them using template functions, or apply Twig filters.

Results

This tutorial demonstrated installing Twig through Composer, as well as displaying simple variables using separate template files. This series takes a closer look at using Twig syntax to develop template files.

Tags: ,

In this article, we will look at Twig tags - template engine constructs that perform a variety of tasks, such as: conditional statements, loops, data escaping, creating macros, using template inheritance, writing to variables and much more. In general, they are written using an opening tag and a closing tag (called the end prefix). Not all constructs need a closing tag. An example of an abstract tag looks like this:

(% tag %) (% endtag %)

Control constructs: conditional statements and loops

if tag

The if tag in Twig is comparable to the conditional if statement in PHP. In its simplest form, you can use it to test whether an expression is true:

(% if label_display == "after" %) (( label )) (% endif %)

You can also test an array or string for existence:

(% if page.footer_fifth %)

(% endif %)

The Twig template engine requires additional checks in the following conditions:

empty- checks if the variable is empty:

(# returns true if foo is null, false, an empty array, or an empty string #) (% if foo is empty %) ... (% endif %) (# possible with the negation operator not #) (% if foo is not empty %) ... (% endif %)

even and odd- returns true if the given number is even or odd, respectively:

(( if var is even )) ... (% endif %) (( if var is odd )) ... (% endif %)

iterable- checks whether the variable is an array or an object (an instance of a class that implements the Traversable interface):

(% if users is iterable %) (% for user in users %) Hello (( user.name ))! (% endfor %) (% else %) (# users is probably the string #) Hello (( users ))! (% endif %)

null- returns true if the variable is equal to NULL:

(( if var is null )) ... (% endif %)

constant- checks whether a variable has exactly the same value as a constant. You can use either global constants or class constants:

(% if status is constant("MARK_NEW") %) (( "New"|t )) (% elseif status is constant("MARK_UPDATED") %) (( "Updated"|t )) (% endif %)

divisible- checks whether a variable is divisible by a number:

(% if loop.index is divisible by(3) %) ... (% endif %)

same as- checks whether two variables point to the same memory location. Similar to the equivalence operator === in php:

(% if foo.attribute is same as(false) %) foo.attribute is equivalent to "false" (% endif %)

defined- checks whether a variable is defined:

(# defined works both with variable names #) (% if foo is defined %) ... (% endif %) (# and with variable attributes #) (% if foo.bar is defined %) ... (% endif %) (% if foo["bar"] is defined %) ... (% endif %)

You can use the logical operators and, or, not in conditions:

(% if not page %) (% if foo and bar %) (% if foo or bar %) (# Complex compound conditions are also possible #) (% if (a and b) or (c and d) %)

It is possible to use regular expressions in the conditions

(% if phone matches "/^[\\d\\.]+$/" %) (% endif %)

You can also check whether a string starts or ends with a specific character:

(% if "Drupal" starts with "D" %) (% endif %) (% if "Drupal" ends with "l" %) (% endif %)

You can also use more complex if-elseif statements (by the way switch-case is missing in Twig):

(% if rows %)

((rows))
(% elseif empty %)
(( empty ))
(% else %) else output (% endif %)

for tag

The for tag is similar to the for construct in PHP and iterates through array elements or object properties if the object is an instance of a class that implements the Traversable interface.

As an example, consider a field template and iterate over multiple field values:

(% for item in items %) ((item.content))(%endfor%)

Variables available inside the loop:

  • loop.index - Current loop iteration (starts at 1)
  • loop.index0 - Current loop iteration (starts at 0)
  • loop.revindex - Number of iterations since the end of the loop (starts at 1)
  • loop.revindex0 - Number of iterations since the end of the loop (starts at 0)
  • loop.first - Flag equal to True if the current iteration is the first
  • loop.last - Flag equal to True if the current iteration is the last one
  • loop.length - Number of elements in the sequence
  • loop.parent - Parent context (used for nested loops)

Unlike PHP, you cannot interrupt or continue the loop (continue and break). However, you can create rules that allow you to skip elements based on conditions for-if. In the example below, inactive users are skipped through iterations:

    (% for user in users if user.status %)
  • ((user.name))
  • (%endfor%)

Also possible in Twig for-else construct to perform actions if the array or object is empty:

    (% for user in users %)
  • ((user.name))
  • (%else%)
  • (( no_found|t ))
  • (%endfor%)

Twig also allows iterations over both keys and values.

(% for key, value in values ​​%)

  • (( key )): (( value ))
  • (%endfor%)

    Template inheritance in Twig

    Template inheritance is one of the most interesting features in Twig. Inheritance allows you to create basic parent templates, which can then be used in child templates, while all the code from the parent templates is also available in the children, and in addition, it is possible to override some blocks of the parent templates. Let's look at tags that allow you to implement inheritance:

    extends tag

    Let's look at the use of inheritance and the extends tag using the example of a template for the block.html.twig block and its child templates. The basic parent block template contains the code in a simplified form:

    (( title_prefix )) (% if label %) ((label))(% endif %) (( title_suffix )) (% block content %) (( content )) (% endblock %)

    The template contains code that will be displayed in child templates. Template content that is available for overriding in child templates is located inside block tags. Each block section has its own name, which will be used when redefining. In this example there is only one block called content. All code outside the block tags will be displayed as is and cannot be redefined. If the block output is not overridden in the child template, the block code will be taken from the base template. As a child template, consider a template for a block with tabs (in Drupal 8 they are placed in a separate block) block--local-tasks-block.html.twig:

    (# Will inherit block.html.twig from the current theme #) (% extends "block.html.twig" %) (% block content %) (% if content %)

    (% endif %) (% endblock %)

    You can also inherit templates from modules and other themes:

    (# Will inherit block.html.twig from the block module (core/modules/block/templates/block.html.twig) #) (% extends "@block/block.html.twig" %) (# Will inherit block. html.twig from the classy theme from the block/ directory (core/themes/classy/templates/block/block.html.twig) #) (% extends "@classy/block/block.html.twig" %)

    When redefining a parent template block, the contents from the parent block are overwritten, but if the contents of the parent block need to be displayed in the block, then the Twig parent() function is used

    (% block content %)

    Header

    ... (( parent() )) (# Prints the contents of the parent block #) (% endblock %)

    Block tag

    Blocks are used to implement the inheritance mechanism as placeholders in both the parent and child templates (more details in the tag section). Block names must consist of numbers, letters, and underscores. The use of dashes is not allowed.

    Macros in Twig

    Macros can be compared to functions in programming languages. They are needed for reusing frequently used parts of html code, and at the same time macros can take parameters, which allows you to dynamically change the inserted code. A static block with html code can be saved using the set tag. Macros differ from PHP functions in the following ways:

    • default arguments in macros are specified inside the macro body;
    • arguments in macros are always optional;
    • if more arguments are passed to the macro than the parameters described, then all of them will be contained in the varargs variable.

    Like PHP functions, macros do not have access to global template variables. To pass variables from the template, if necessary, you need to use the special variable _context.

    Tag macro

    The macro tag defines a new macro. As a simple example, consider a macro that renders an input form element, with the macro containing input type, name, value, size as parameters (type and size are set by default):

    (%endmacro%)

    (# Import macros from forms.html.twig into the current template #) (% import "forms.html" as forms %) (# Call the macro #)

    (( forms.input("username") ))

    If a macro is defined and used in the same template, then the special variable _self is used to import it.

    (% import _self as forms %)

    (( forms.input("username") ))

    If you need to use a macro in another macro, but in the same template, then the macro is imported locally inside the other macro:

    (% macro input(name, value, type, size) %) (% endmacro %) (% macro wrapped_input(name, value, type, size) %) (% import _self as forms %)

    (( forms.input(name, value, type, size) ))
    (%endmacro%)

    In Drupal 8, in the menu.html.twig template, the menu_links() macro is defined and used in the same template, and additionally the macro itself is used recursively within itself to display nested menu items:

    (% import _self as menus %) (( menus.menu_links(items, attributes, 0) )) (% macro menu_links(items, attributes, menu_level) %) (% import _self as menus %) (% if items %) ( % if menu_level == 0 %) (%else%)

      (% endif %) (% for item in items %) (( link(item.title, item.url) )) (% if item.below %) (( menus.menu_links(item.below, attributes, menu_level + 1) )) (% endif %)(%endfor%)
    (% endif %) (% endmacro %)

    import tag

    The import tag imports all macros from the specified template:

    (# forms.html.twig #) (# Describe the macro input() #) (% macro input(name, value, type, size) %) (% endmacro %) (# Describe the macro textarea() #) (% macro textarea(name, value, rows, cols) %) (% endmacro %) (# Import macros from forms.html.twig into another template #) (% import "forms.html" as forms %)

    Username
    (( forms.input("username") ))
    Password
    (( forms.input("password", null, "password") ))

    (( forms.textarea("comment") ))

    From tag

    The from tag imports only the specified macros from the template:

    (# Import macros from forms.html.twig: input() with alias input_field and textarea() #) (% from "forms.html" import input as input_field, textarea %)

    Username
    (( input_field("username") ))
    Password
    (( input_field("password", "", "password") ))

    (( textarea("comment") ))

    include tag

    The include tag includes the name of the template and returns the rendered contents of that file to the current template. All variables of the current template will be available in connected templates. Using include, you can put some code blocks into separate templates:

    (#header.html.twig#)

    ((header))
    (#footer.html.twig#)
    ((footer))
    (# page.html.twig - available variables: header, footer #) (% include "header.html" %)
    Body
    (% include "footer.html" %) (# Result:
    Header
    Body
    Footer
    #}

    You can add additional variables by passing them after with:

    (# template.html.twig will have access to variables from the current template context and added variables #) (% include "template.html" with ("foo": "bar") %) (% set vars = ("foo" : "bar") %) (% include "template.html" with vars %) (# You can also add multiple variables #) (% include "template.html" with ("foo": var1, "bar" : var2) %) (# Variables foo and bar will be available in template.html.twig #)

    Or you can disable access to the context by adding only.

    (# Only the foo variable will be available in template.html.twig #) (% include "template.html" with ("foo": "bar") only %) (# There will be no access to variables in template.html.twig # ) (% include "template.html" only %)

    You can override include with the ignore missing statement, which will cause Twig to ignore the inclusion of a non-existent template. The ignore missing statement is placed immediately after the template name:

    (% include "sidebar.html" ignore missing %) (% include "sidebar.html" ignore missing with ("foo": "bar") %) (% include "sidebar.html" ignore missing only %)

    You can also provide a list of templates that are checked for existence before inclusion.

    (% include ["page_detailed.html", "page.html"] %) (% include ["special_sidebar.html", "sidebar.html"] ignore missing %)

    An example of using include in Drupal 8 can be seen in the Classy links--node.html.twig theme template:

    (% if links %)

    (% endif %) (# In the connected template links.html.twig all variables from links--node.html.twig are available #)

    Set tag

    You can create variables inside templates using the set tag:

    (# Write a string to a variable #) (% set foo = "foo" %) (# Write an array to a variable #) (% set foo = %) (# Write an associative array to a variable #) (% set foo = ("foo ": "bar") %) (# ~ character concatenates strings #) (% set foo = "foo" ~ "bar" %) (# Result: foo contains "foobar" #) (% set foo, bar = " foo", "bar" %) (# Created two variables foo and bar #)

    Using the set tag, you can write a block of code to a variable:

    (%set foo%)

    (% endset %)

    Tag spaceless

    The spaceless tag can be used to remove spaces between HTML tags, as well as content within HTML tags or spaces in plain text:

    (% spaceless %)

    foo
    (% endspaceless %) (# Result:
    foo
    #}

    Tag autoescape

    Depending on whether auto-escaping is enabled or not, you can mark a template fragment for escaping or disable this feature using the autoescape tag (in Drupal 8, auto-escaping is enabled in the html context):

    (% autoescape %) Auto-escaping in this block is performed using HTML methods. (% endautoescape %) (% autoescape "html" %) Auto-escaping in this block is performed using HTML methods. (% endautoescape %) (% autoescape "js" %) Auto-escaping in this block is performed by js methods. (% endautoescape %) (% autoescape false ) Auto-escaping is disabled. The contents of the block are displayed unchanged. (%endautoescape%)

    verbatim tag

    The verbatim tag marks the section and tells the template engine not to process the contents of the block:

    (% verbatim%)

      (% for item in items %)
    • ((item))
    • (%endfor%)
    (% endverbatim %) (# Result:
      (% for item in items %)
    • ((item))
    • (%endfor%)
    #}

    filter tag

    The filter tag allows you to apply standard Twig template engine filters to template data blocks. Just place the code inside the "filter" section:

    (% filter upper %) Drupal 8 (% endfilter %) (# Result: "DRUPAL 8" #)

    You can also create combinations of filters:

    (% filter lower|escape %) SOME TEXT(% endfilter %) (# Result: " some text" #}

    If the tag uses escape or e filters, then drupal will replace them with its drupal_escape filter.

    tag do

    The do tag works the same as a standard variable expression ((var)), with the difference that nothing is output. In practice, it is applicable if you need to call a function or method of an object that can return or output something, but this data does not need to be displayed in the template output.

    (% do 1 + 2 %) (% do product.delete() %)

    Trans tag

    The trans tag is specific to Drupal 8. This tag allows you to translate text (using tokens) inside a tag using the t() function or TranslationManager::formatPlural() if the construct is used inside the tag (% plural ... %):

    While studying the Symfony framework, sooner or later you will come across such a concept as a template engine. Let's now understand what a template engine is and why it is needed.

    Symfony uses a template engine called Twig. In fact, Twig is not the only template engine that you and I can use. You can use any other template engine.

    But, by default, Symfony uses the Twig template engine.

    Let's figure out why we need a template engine and for what purposes it is used.

    If we remember the MVC model (model - view - controller), which we talked about a little earlier, then the template engine is what belongs to the “View” part.

    As you remember, our task is to present the data that will be issued at the user’s request. Exactly the same template engine. Its main task is to present data for display to the user.

    A template engine file is a regular text file. For Twig this file has 2 extensions.

    This means that this file contains HTML markup and secondly, this file is a service file of the Twig template engine.

    Essentially, this file contains 2 parts: regular html code with simple html tags, built-in CSS styles, built-in Javascript code, etc.

    Unlike a regular HTML page, in addition to the document markup, it also displays certain data that could have been transferred to it from the controller. Using special constructs, this data is embedded in the source twig file.

    The data on the server can change and automatically it also changes in the twig file. Those. we received an html page that contains some data from the web server.

    In addition to data, the twig file may contain some utility functions that simplify the presentation of this data.

    Those. a template engine is something like a template, and into this template we can pass certain variables that depend on the state of our server.

    Therefore, the template engine comes from the word “template”. It contains some kind of template page, template HTML code and variable data is inserted into it.

    Those. A template engine is something like a service that prepares an HTML page with all the necessary data that reflects the state of our web server and returns this data to the controller.

    And the controller already returns the finished HTML code to that site visitor. who requested it.

    This is how it works. I hope that it has become clearer what a template engine is and why it is needed, and now we can begin to consider specific examples of working with this tool.

    We figured out the configs and parameter values. Today we will learn how to display settings in the browser. And so that it doesn’t get boring just writing html, let’s connect the Twig template engine to the project. The main part of the article will be devoted to him.

    Twiga has excellent functionality and simple syntax. We won’t go into the wilds; a small part of its capabilities will be enough for us. Begin.

    We connect Twig and render the first template.

    I wanted to download the latest version of twig-a 2.x, but I failed. It is installed via composer, but I am not familiar with it. I suspect that composer is not much different from front-line npm or bower, but we won’t dive into it now. Those who are in the know will do it composer require "twig/twig:^2.0" and without me, and I, like a normal PHP guy, download version 1.x via Download zip and don’t worry. Download from here https://github.com/twigphp/Twig/tree/1.x

    We are looking for a place for Twig in the project. Let's create a folder admin/lib/Twig and add the library there. Ideally, we could do it without composer.

    Go ahead. Twig needs a cache folder where he can freely write rendered templates. The debatable question is, where do normal guys define the cache folder? Without imagination, I created it directly in admin - admin/cache. Well, God be with her. The main thing is to make sure that the www-data user is allowed to write to it. If you're on Windows, then don't care. And if not, then change the owner and give write permission to the cache

    $ sudo chown -R www-data:www-data ./cache $ sudo chmod -R 755 ./cache/

    The last thing a twig needs is to know where to get templates. To do this, make a folder admin/templates and drop index.html with content into it Hello, ((name)). Yeah, we’re already learning the magic. The name value will be passed to the template externally, from the php file.

    Let's connect twig to admin/index.php and render the template. From time immemorial, the author has included markup in index.php, but now he doesn’t. He has matured. The php file will do what it should - the application logic. It even sounds nice, so it’s time to implement it.

    // Connect the template engine require_once "./lib/Twig/Autoloader.php"; // Initialize Twig Twig_Autoloader::register(); $loader = new Twig_Loader_Filesystem("./templates"); $twig = new Twig_Environment($loader, array("cache" => "./cache", "debug" => true)); // Render the template echo $twig->render("index.html", array("name" => "Twig"));

    In the first line we connect the twig itself. Next is initialization. I read in the documentation that if an Unforeseen Event occurs and for some reason DOES NOT WORK, then write Twig_Autoloader::register();
    I am a luck person and I caught that very chance. I wrote what I was told to do, and everything became fine. I hope you have better luck and instead of 10 lines, fit into 9.

    Next, in $loader and $twig we load the environment or something necessary for the template engine. In the parameters we specify the path to the templates and cache folders and the important parameter debug=true. On the combat site, remove debug, but leave it for now. Otherwise, when changing the template in templates/index.html, the twig will not care and will immediately take the rendered one from the cache. And we will be surprised that we edit this template, but it does not change in the browser.

    So, let's refresh the page and see the text Hello Twig. Congratulations, our first template worked. But before filling it with useful content, let's change index.php a little. Or rather, let’s connect the admin class and add settings to the template rather than name=Twig. It will turn out like this.

    // Connect the template engine and admin class require_once "./lib/Twig/Autoloader.php"; require_once "./admin.class.php"; // Initialize Twig Twig_Autoloader::register(); $loader = new Twig_Loader_Filesystem("./templates"); $twig = new Twig_Environment($loader, array("cache" => "./cache", "debug" => true)); // Create an admin object $admin = new Admin(); // Render the template echo $twig->render("index.html", array("settings" => $admin->getSettings()));

    Editing the template.

    The prototype was highlighted in the previous article. This is what we are focusing on. We will need a template HTML document and a simple form with parameter names and values.

    Of course, the form will be in bootstrap. One day I'll get big and show some other CSS framework, but for now I'm lazy. I justify myself by the fact that we are not coding CSS, but PROGRAMMING APPLICATIONS. While the excuse is working, we return to the template.

    I take the template from the bootstrap website. In the head, copy and paste this

    And you will have to write the body yourself.

    It looks like a regular bootstrap form, but with Twig inserts.
    Let's take it one by one.

    (% for item in settings %)

    We go through the settings in a loop and for each we display a label and input in the form.

    item.key is used both as an ID and as the name of the input, and as the value of the for in the label. Such an important necessary key.
    item.title - title of the setting.

    And this is a text field with a value.

    Now we refresh the page and see a list of settings with the required values. Beauty! Change the field values ​​in config/values.json. It works, again beauty.

    The author would end the article with this positive sentence, but it is impossible. Because an attentive reader will say: stop, but the picture is not the same! Doesn't match the prototype. And the inquisitive reader will also ask: why was there so much fuss with configs and different data types in the first lesson? To now output them stupidly into inputs? Of course, the reader is right. So the author will go have some tea and write a couple more paragraphs.

    So let's continue. We want to output different select inputs depending on the type of setting. The twig conditions and the type field from the settings config will help with this. There are 4 types of settings: text, number, checkbox and select. We make a condition for each of them. Instead of

    we write like this

    (% if item.type == "text" %) (% endif %) (% if item.type == "number" %) (% endif %) (% if item.type == "checkbox" %)

    (% endif %) (% if item.type == "select" %) (% for option in item.list %) (( option )) (% endfor %) (% endif %)

    It seems like a lot and spread out, but let’s look closer and it will become clearer.

    1. the text input was simply wrapped in the condition item.type == "text"
    2. number - the same input, only with type="number"
    3. there is a separate layout for checkbox. It’s logical, a checkbox is not just an input.
      Don't forget about the checked attribute, which is set depending on item.value (true or false).
      Interestingly, the checkbox itself does not have a name attribute with the value item.key. But the hidden input next to the checkbox has name.
      Spoiler: this is more convenient for sending the form to the backend, we’ll see in the next article.
    4. select has a loop because we display a list of possible values ​​from the item.list field

    Now let's refresh the page again. I got it like this

    That's it now. You can play with the settings and values ​​in the json files and see how it successfully spreads across the form.

    If you are inspired by the twig and want to learn more, here is the documentation in Russian. https://x-twig.ru/intro/

    The next lesson will be the final one on the topic of “administration on files”. We will write js code that will send data to the backend, and php code that will save this data. As a bonus, we will implement notifications so that the user can see if he forgot to click the save button.

    A little poll at the end and see you later!