{"id":13409328,"url":"https://github.com/squirrelphp/twig-php-syntax","last_synced_at":"2025-04-13T06:41:36.330Z","repository":{"id":57058438,"uuid":"257924334","full_name":"squirrelphp/twig-php-syntax","owner":"squirrelphp","description":"Adds common PHP syntax to twig templates, like ===, foreach and strtotime","archived":false,"fork":false,"pushed_at":"2024-05-01T12:20:29.000Z","size":70,"stargazers_count":49,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-09-30T23:09:41.774Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/squirrelphp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-22T14:23:45.000Z","updated_at":"2024-09-04T13:58:38.000Z","dependencies_parsed_at":"2024-06-19T00:05:52.159Z","dependency_job_id":"ac9a4e0a-6546-403b-a8f2-d1f7c92d34eb","html_url":"https://github.com/squirrelphp/twig-php-syntax","commit_stats":{"total_commits":15,"total_committers":1,"mean_commits":15.0,"dds":0.0,"last_synced_commit":"97738f7533de0fd5ed8f03d052d219bd23398976"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelphp%2Ftwig-php-syntax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelphp%2Ftwig-php-syntax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelphp%2Ftwig-php-syntax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelphp%2Ftwig-php-syntax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/squirrelphp","download_url":"https://codeload.github.com/squirrelphp/twig-php-syntax/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248675434,"owners_count":21143763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T20:00:59.935Z","updated_at":"2025-04-13T06:41:36.306Z","avatar_url":"https://github.com/squirrelphp.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"PHP Syntax for Twig\n===================\n\n![Test Coverage](https://img.shields.io/badge/style-100%25-success.svg?style=flat-round\u0026label=test%20coverage) ![PHPStan](https://img.shields.io/badge/style-level%2max-success.svg?style=flat-round\u0026label=phpstan) [![Packagist Version](https://img.shields.io/packagist/v/squirrelphp/twig-php-syntax.svg?style=flat-round)](https://packagist.org/packages/squirrelphp/twig-php-syntax) [![PHP Version](https://img.shields.io/packagist/php-v/squirrelphp/twig-php-syntax.svg)](https://packagist.org/packages/squirrelphp/twig-php-syntax) [![Software License](https://img.shields.io/badge/license-MIT-success.svg?style=flat-round)](LICENSE)\n\nEnables syntax known from PHP in Twig, so PHP developers can more easily create and edit Twig templates. This is especially useful for small projects, where the PHP developers end up writing Twig templates and it is not worth it to have a slightly different syntax in your templates.\n\nInstallation\n------------\n\n    composer require squirrelphp/twig-php-syntax\n\nConfiguration\n-------------\n\nAdd PhpSyntaxExtension to Twig:\n\n```php\n$twig = new \\Twig\\Environment($loader);\n$twig-\u003eaddExtension(new \\Squirrel\\TwigPhpSyntax\\PhpSyntaxExtension());\n```\n\nYou can also have a look at the extension definition and create your own extension class to only include some of the features, if you do not like all of them.\n\n### Symfony integration\n\nIf you use `autoconfigure` (which is the default) you just need to load the PhpSyntaxExtension class in `services.yaml` in the `config` directory of your project (the first four lines should already be there, just add the line with the PhpSyntaxExtension class at the end of the file):\n\n```yaml\nservices:\n    _defaults:\n        autowire: true\n        autoconfigure: true\n\n    # Just add the following line, Symfony will register\n    # the extension in Twig for you if Twig is installed\n    Squirrel\\TwigPhpSyntax\\PhpSyntaxExtension: ~\n```\n\nIf you do not use `autoconfigure`, you can add the twig extension tag to the service definition:\n\n```yaml\nservices:\n    Squirrel\\TwigPhpSyntax\\PhpSyntaxExtension:\n        tags:\n            - { name: twig.extension }\n```\n\nFeatures\n--------\n\n### === / !== strict comparison operators\n\nTwig has the `same as` test, which mimicks `===` in PHP, but has a syntax that can be hard to get used to. Using the strict comparison operators from PHP (`===` and `!==`) reduces friction, is familiar and less verbose.\n\n```twig\n{% if 1 === 1 %}\nThis will be shown\n{% endif %}\n\n{% if 1 is same as(1) %}\nSame as above but with standard Twig syntax\n{% endif %}\n\n\n{% if 1 === '1' %}\nThis will not be shown, as 1 and '1' have different types (string vs. integer)\n{% endif %}\n\n\n{% if somevariable === \"test\" %}\nsomevariable is of type string and equals \"test\"\n{% endif %}\n\n{% if somevariable !== \"test\" %}\nsomevariable either is not a string or does not equal \"test\"\n{% endif %}\n```\n\n### strtotime filter\n\nComparing timestamps in templates when the data only has (date) strings is a bit cumbersome in Twig, as there is no `strtotime` filter - this library adds it exactly as it is in PHP:\n\n```twig\n{% if \"2018-05-05\"|strtotime \u003e \"2017-05-05\"|strtotime %}\nThis is always true, as 2018 results in a larger timestamp integer than 2017\n{% endif %}\n\n{% if post.date|strtotime \u003e otherpost.date|strtotime %}\nCompares the dates of post and otherpost. strtotime returns an integer\nor throws an InvalidArgumentException if strtotime returns false\n{% endif %}\n\n{# Sets next thursday as a timestamp variable, but also sets \"now\"\nlike in strtotime in PHP to define from where the timestamp is\ncalculated if it is a relative date and not an absolute date #}\n{% set nextThusday = \"next Thursday\"|strtotime(now=sometimestamp) %}\n```\n\n### foreach loops\n\nTwig uses `for` to create loops, with a slightly different syntax compared to `foreach` in PHP. With this library `foreach` becomes available in Twig with the same syntax as in PHP:\n\n```twig\n{% foreach list as sublist %}\n  {% foreach sublist as key =\u003e value %}\n  {% endforeach %}\n{% endforeach %}\n```\n\nInternally it behaves the exact same way as `for`: it actually creates ForNode elements, so you have the same functionality like in `for` loops, including [the `loop` variable](https://twig.symfony.com/doc/3.x/tags/for.html#the-loop-variable) and `else`. `else` works the same as with `for`:\n\n```twig\n{% foreach list as sublist %}\n  {% foreach sublist as key =\u003e value %}\n  {% else %}\n    Array \"sublist\" is empty / no iteration took place\n  {% endforeach %}\n{% else %}\n  Array \"list\" is empty / no iteration took place\n{% endforeach %}\n```\n\n### break and continue\n\nSometimes it can be convenient to break loops in Twig, yet there is no native support for it. This library adds `break` and `continue` and they work exactly as in PHP:\n\n```twig\n{% foreach list as entry %}\n  {% if loop.index \u003e 10 %}\n    {% break %}\n  {% endif %}\n{% endforeach %}\n```\n\nYou can use `break` with a number to break out of multiple loops, just like in PHP: (`continue` does not support this)\n\n```twig\n{% foreach list as sublist %}\n  {% foreach sublist as entry %}\n    {% if loop.index \u003e 10 %}\n      {% break 2 %} {# breaks out of both foreach loops #}\n    {% endif %}\n  {% endforeach %}\n{% endforeach %}\n```\n\nWhile you can often circumvent the usage of `break` and `continue` in Twig, it sometimes leads to additional nesting and more complicated code. Just one `break` or `continue` can clarify behavior and intent in these instances. Yet I would advise to use `break` and `continue` sparingly.\n\n### Variable type tests (string, array, true, callable, etc.)\n\nAdds tests known from PHP, so you can test a value for being:\n\n - an array (like `is_array`)\n - a boolean (like `is_bool`)\n - a callable (like `is_callable`)\n - a float (like `is_float`)\n - an integer (like `is_int`)\n - an object (like `is_object`)\n - a scalar (integer, float, string or boolean, like `is_scalar`)\n - a string (like `is_string`)\n - true (like `=== true`)\n - false (like `=== false`)\n\n It uses the mentioned PHP functions / comparisons internally, so you have the same behavior as in PHP.\n\n```twig\n{% if someflag is true %} {# instead of {% if someflag is same as(true) %} #}\n{% endif %}\n\n{% if someflag is false %} {# instead of {% if someflag is same as(false) %} #}\n{% endif %}\n\n{% if somevar is string %} {# no equivalent in Twig %} #}\n{% endif %}\n\n{% if somevar is scalar %} {# no equivalent in Twig %} #}\n{% endif %}\n\n{% if somevar is object %} {# no equivalent in Twig %} #}\n{% endif %}\n\n{% if somevar is integer %} {# no equivalent in Twig %} #}\n{% endif %}\n{% if somevar is int %} {# same as integer test above, alternate way to write it %} #}\n{% endif %}\n\n{% if somevar is float %} {# no equivalent in Twig %} #}\n{% endif %}\n\n{% if somevar is callable %} {# no equivalent in Twig %} #}\n{% endif %}\n\n{% if somevar is boolean %} {# no equivalent in Twig %} #}\n{% endif %}\n{% if somevar is bool %} {# same as boolean test above, alternate way to write it %} #}\n{% endif %}\n\n{% if somevar is array %} {# no equivalent in Twig %} #}\n{% endif %}\n```\n\n### Convert to type: intval, strval, floatval and boolval filters\n\nConverting a variable to a specific type is not something Twig encourages and it probably should be avoided, if possible. Yet there are situations where you just want to convert something to an integer or string so you can be sure a comparison is type safe or that there is no unexpected behavior because one value has the wrong type.\n\n```twig\n{% if '5'|intval === 5 %}\nConvert '5' to an integer - this if block is being executed\n{% endif %}\n\n{% if 5.7|strval === '5.7' %}\nConvert 5.7 to a string - this if block is being executed\n{% endif %}\n\n{% if 1|boolval === true %}\nConvert 1 to a boolean - this if block is being executed\n{% endif %}\n\n{% if '5.7'|floatval === 5.7 %}\nConvert '5.7' to a float - this if block is being executed\n{% endif %}\n```\n\nThese filters mainly behave like the ones in PHP (and use the corresponding PHP functions internally), but there is some additional behavior to detect or avoid likely errors:\n\n- only scalar values, null and objects with a __toString method are allowed, so if you use any of these filters with an array or an object that cannot be cast to a string it will throw an exception\n- null will return 0 for intval, '' for strval, false for boolval and 0.0 for floatval (just like in PHP)\n- objects with a __toString method will be converted to a string first (using the __toString method), and only after that intval, boolval and floatval will be used\n- boolval should be used with caution, as if you give it any non-numeric string it will return true, yet empty strings and \"0\" will return false. boolval is here more for completeness, as it is probably the least useful conversion function in PHP. The recommendation is to use the other three functions instead of using boolval if possible.\n\n### \u0026\u0026 and ||\n\nIf you want to make expressions even more like PHP, you can use `\u0026\u0026` instead of `and` and `||` instead of `or`. This might be the least useful part of this library, as `and` and `or` are already short and clear, yet it is another easily remedied difference between Twig and PHP, and `\u0026\u0026` and `||` can be easier to spot in comparison to `and` and `or`.\n\n```twig\n{% if someflag === true \u0026\u0026 otherflag === false %}\ninstead of if someflag === true and otherflag === false\n{% endif %}\n\n{% if someflag === true || otherflag === true %}\ninstead of if someflag === true or otherflag === false\n{% endif %}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquirrelphp%2Ftwig-php-syntax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquirrelphp%2Ftwig-php-syntax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquirrelphp%2Ftwig-php-syntax/lists"}