├── tests ├── tests │ ├── Field │ │ ├── Stubs │ │ │ ├── tmpl │ │ │ │ ├── another.html.twig │ │ │ │ └── default.html.twig │ │ │ └── SampleField.php │ │ └── BaseLayoutFieldTest.php │ ├── Loader │ │ ├── Stubs │ │ │ ├── tmpl │ │ │ │ └── default.html.twig │ │ │ └── SampleLoader.php │ │ ├── TemplateLoaderTest.php │ │ ├── ModuleLoaderTest.php │ │ ├── ComponentLoaderTest.php │ │ ├── LibraryLoaderTest.php │ │ └── BaseExtensionLoaderTest.php │ ├── Module │ │ └── Stubs │ │ │ └── SampleTwigModule.php │ ├── View │ │ └── Traits │ │ │ ├── Stubs │ │ │ └── ClassWithTwigRenderer.php │ │ │ └── HasTwigRendererTest.php │ ├── Plugin │ │ ├── Stubs │ │ │ └── SamplePlugin.php │ │ └── BasePluginTest.php │ ├── Mock │ │ └── TwigMock.php │ ├── Extension │ │ ├── UnerializeTest.php │ │ ├── JUriTest.php │ │ ├── JUserTest.php │ │ ├── JRouteTest.php │ │ ├── Traits │ │ │ ├── HasFunctions.php │ │ │ └── HasFilters.php │ │ ├── JHtmlTest.php │ │ ├── JSessionTest.php │ │ ├── JProfilerTest.php │ │ ├── JTextTest.php │ │ ├── JModuleHelperTest.php │ │ ├── JArrayTest.php │ │ ├── JLanguageTest.php │ │ ├── JRegistryTest.php │ │ ├── JLayoutTest.php │ │ └── JPositionTest.php │ └── Traits │ │ └── HasParamsTest.php └── bootstrap.php ├── docs ├── _data │ ├── nav.yml │ └── sidebar.yml ├── images │ └── workflow.jpg ├── _config.yml ├── globals │ ├── juri.md │ ├── jdoc.md │ ├── jsession.md │ ├── japp.md │ ├── jlang.md │ └── juser.md ├── filters │ ├── to_array.md │ └── unserialize.md ├── functions │ ├── jposition.md │ ├── jlang.md │ ├── jmodule_render_module.md │ ├── jmodule_get_modules.md │ ├── jregistry.md │ ├── jhtml.md │ ├── jtext_sprintf.md │ ├── juser.md │ ├── jlayout_render.md │ ├── jlayout_debug.md │ ├── jroute.md │ ├── jtext.md │ ├── juri.md │ ├── jmodule_get_module.md │ ├── jprofiler.md │ └── jlayout.md └── README.md ├── ci ├── test.sh ├── gulp-config.ci.json ├── setup.sh └── phpunit.ci.xml ├── Gemfile ├── COPYING.txt ├── extensions ├── plugins │ └── twig │ │ ├── cache │ │ ├── language │ │ │ └── en-GB │ │ │ │ ├── en-GB.plg_twig_cache.sys.ini │ │ │ │ └── en-GB.plg_twig_cache.ini │ │ ├── cache.xml │ │ └── cache.php │ │ ├── juri │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_juri.sys.ini │ │ ├── juri.xml │ │ └── juri.php │ │ ├── jarray │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jarray.sys.ini │ │ ├── jarray.xml │ │ └── jarray.php │ │ ├── jdoc │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jdoc.sys.ini │ │ ├── jdoc.xml │ │ └── jdoc.php │ │ ├── jhtml │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jhtml.sys.ini │ │ ├── jhtml.xml │ │ └── jhtml.php │ │ ├── jtext │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jtext.sys.ini │ │ ├── jtext.xml │ │ └── jtext.php │ │ ├── juser │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_juser.sys.ini │ │ ├── juser.xml │ │ └── juser.php │ │ ├── japp │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_japp.sys.ini │ │ ├── japp.xml │ │ └── japp.php │ │ ├── jlang │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jlang.sys.ini │ │ ├── jlang.xml │ │ └── jlang.php │ │ ├── jroute │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jroute.sys.ini │ │ ├── jroute.xml │ │ └── jroute.php │ │ ├── jsession │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jsession.sys.ini │ │ ├── jsession.xml │ │ └── jsession.php │ │ ├── jlayout │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jlayout.sys.ini │ │ ├── jlayout.xml │ │ └── jlayout.php │ │ ├── jprofiler │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jprofiler.sys.ini │ │ ├── jprofiler.xml │ │ └── jprofiler.php │ │ ├── jmodule │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jmodule.sys.ini │ │ ├── jmodule.xml │ │ └── jmodule.php │ │ ├── jregistry │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jregistry.sys.ini │ │ ├── jregistry.xml │ │ └── jregistry.php │ │ ├── jposition │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_jposition.sys.ini │ │ ├── jposition.xml │ │ └── jposition.php │ │ ├── unserialize │ │ ├── language │ │ │ └── en-GB │ │ │ │ └── en-GB.plg_twig_unserialize.sys.ini │ │ ├── unserialize.xml │ │ └── unserialize.php │ │ └── debug │ │ ├── language │ │ └── en-GB │ │ │ └── en-GB.plg_twig_debug.sys.ini │ │ ├── debug.xml │ │ └── debug.php ├── language │ └── en-GB │ │ └── en-GB.pkg_twig.sys.ini ├── libraries │ └── twig │ │ ├── form │ │ └── field │ │ │ ├── viewlayout.php │ │ │ ├── modulelayout.php │ │ │ └── pluginlayout.php │ │ ├── language │ │ └── en-GB │ │ │ └── en-GB.lib_twig.ini │ │ ├── composer.json │ │ ├── src │ │ ├── View │ │ │ ├── ItemFormView.php │ │ │ ├── FormView.php │ │ │ ├── ItemView.php │ │ │ ├── HtmlView.php │ │ │ ├── ListView.php │ │ │ └── Traits │ │ │ │ └── HasTwigRenderer.php │ │ ├── Extension │ │ │ ├── Unserialize.php │ │ │ ├── JUri.php │ │ │ ├── JUser.php │ │ │ ├── JRoute.php │ │ │ ├── JSession.php │ │ │ ├── JLanguage.php │ │ │ ├── JProfiler.php │ │ │ ├── JText.php │ │ │ ├── JHtml.php │ │ │ ├── JArray.php │ │ │ ├── JRegistry.php │ │ │ ├── JModuleHelper.php │ │ │ ├── JLayout.php │ │ │ └── JPosition.php │ │ ├── Plugin │ │ │ └── BasePlugin.php │ │ ├── Traits │ │ │ ├── HasLayoutData.php │ │ │ ├── HasTwigRenderer.php │ │ │ └── HasParams.php │ │ ├── Loader │ │ │ ├── TemplateLoader.php │ │ │ ├── LibraryLoader.php │ │ │ ├── PluginLoader.php │ │ │ ├── ModuleLoader.php │ │ │ ├── ComponentLoader.php │ │ │ └── ExtensionLoader.php │ │ ├── Twig.php │ │ ├── Field │ │ │ ├── ModuleLayout.php │ │ │ ├── ViewLayout.php │ │ │ └── PluginLayout.php │ │ ├── Module │ │ │ └── BaseTwigModule.php │ │ └── Environment.php │ │ ├── twig.xml │ │ ├── library.php │ │ └── layouts │ │ └── examples.html.twig └── pkg_twig.xml ├── .gitignore ├── phpcs.xml ├── .travis.yml ├── updates └── twig_update.xml ├── sonar-project.properties ├── phpunit.dist.xml ├── composer.json ├── README.md └── CODE_OF_CONDUCT.md /tests/tests/Field/Stubs/tmpl/another.html.twig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/tests/Field/Stubs/tmpl/default.html.twig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/tests/Loader/Stubs/tmpl/default.html.twig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_data/nav.yml: -------------------------------------------------------------------------------- 1 | - title: Getting Started 2 | link: home 3 | -------------------------------------------------------------------------------- /ci/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./vendor/bin/phpcs 3 | ./vendor/bin/phpunit --configuration ci/phpunit.ci.xml 4 | -------------------------------------------------------------------------------- /docs/images/workflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phproberto/joomla-twig/HEAD/docs/images/workflow.jpg -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'github-pages', group: :jekyll_plugins 3 | gem "jekyll-remote-theme" 4 | -------------------------------------------------------------------------------- /ci/gulp-config.ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "wwwDir" : "/tmp/joomla-cms", 3 | "browserConfig" : { 4 | "proxy" : "localhost/joomla-cms" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /COPYING.txt: -------------------------------------------------------------------------------- 1 | Copyright © 2017 Roberto Segura López 2 | 3 | Each file included in this library is licensed under GNU LESSER GENERAL PUBLIC LICENSE 4 | 5 | See LICENSE for the full text of the GNU LESSER GENERAL PUBLIC LICENSE. 6 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: joomla-twig 2 | description: Twig 2.0 & Twig extensions integration for Joomla! 3 | show_nav: false 4 | show_sidebar: true 5 | show_downloads: true 6 | theme: phproberto/jekyll-test 7 | remote_theme: "phproberto/jekyll-test" 8 | include: 9 | - contributing.md 10 | - license.md 11 | plugins: 12 | - jekyll-remote-theme 13 | -------------------------------------------------------------------------------- /extensions/plugins/twig/cache/language/en-GB/en-GB.plg_twig_cache.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_cache 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_CACHE="Twig - Cache" 7 | PLG_TWIG_CACHE_DESC="Enables cache for twig" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDEs 2 | /.idea 3 | .phpintel 4 | *.sublime* 5 | *.code-workspace 6 | .vscode 7 | 8 | # Build 9 | gulp-config.json 10 | node_modules/ 11 | /build/releases 12 | .scannerwork 13 | 14 | # Docs 15 | /_site 16 | 17 | # Composer 18 | /vendor/ 19 | composer.lock 20 | /extensions/libraries/twig/vendor 21 | 22 | # Tests 23 | /clover.xml 24 | /tests/coverage 25 | phpunit.xml 26 | -------------------------------------------------------------------------------- /extensions/plugins/twig/juri/language/en-GB/en-GB.plg_twig_juri.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_juri 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JURI="Twig Extension - juri" 7 | PLG_TWIG_JURI_DESC="Use JUri inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jarray/language/en-GB/en-GB.plg_twig_jarray.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jarray 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JARRAY="Twig Extension - array tools" 7 | PLG_TWIG_JARRAY_DESC="Common tools for arrays" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jdoc/language/en-GB/en-GB.plg_twig_jdoc.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jdoc 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JDOC="Twig Extension - jdoc" 7 | PLG_TWIG_JDOC_DESC="Use JDocument inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jhtml/language/en-GB/en-GB.plg_twig_jhtml.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jhtml 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JHTML="Twig Extension - jhtml" 7 | PLG_TWIG_JHTML_DESC="Use JHtml inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jtext/language/en-GB/en-GB.plg_twig_jtext.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jtext 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JTEXT="Twig Extension - jtext" 7 | PLG_TWIG_JTEXT_DESC="Use JText inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/juser/language/en-GB/en-GB.plg_twig_juser.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_juser 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JUSER="Twig Extension - juser" 7 | PLG_TWIG_JUSER_DESC="Use JUser inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/japp/language/en-GB/en-GB.plg_twig_japp.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_japp 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JAPP="Twig Extension - japp" 7 | PLG_TWIG_JAPP_DESC="Use JApplication inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jlang/language/en-GB/en-GB.plg_twig_jlang.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jlang 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JLANG="Twig Extension - jlang" 7 | PLG_TWIG_JLANG_DESC="Use JLanguage inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jroute/language/en-GB/en-GB.plg_twig_jroute.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jroute 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JROUTE="Twig Extension - jroute" 7 | PLG_TWIG_JROUTE_DESC="Use JRoute inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jsession/language/en-GB/en-GB.plg_twig_jsession.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jsession 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JSESSION="Twig Extension - jsession" 7 | PLG_TWIG_JSESSION_DESC="Use JSession inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jlayout/language/en-GB/en-GB.plg_twig_jlayout.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jlayout 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JLAYOUT="Twig Extension - jlayout" 7 | PLG_TWIG_JLAYOUT_DESC="Use JLayout & JLayoutHelper inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jprofiler/language/en-GB/en-GB.plg_twig_jprofiler.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jprofiler 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JPROFILER="Twig Extension - jprofiler" 7 | PLG_TWIG_JPROFILER_DESC="Use JProfiler inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jmodule/language/en-GB/en-GB.plg_twig_jmodule.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jmodule 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JMODULE="Twig Extension - jmodule" 7 | PLG_TWIG_JMODULE_DESC="Use ModuleHelper common functions in your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jregistry/language/en-GB/en-GB.plg_twig_jregistry.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jregistry 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JREGISTRY="Twig Extension - jregistry" 7 | PLG_TWIG_JREGISTRY_DESC="Use Registry/JRegistry inside your twig templates" 8 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jposition/language/en-GB/en-GB.plg_twig_jposition.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_jposition 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_JPOSITION="Twig Extension - jposition" 7 | PLG_TWIG_JPOSITION_DESC="Load Joomla! module positions inside your twig templates" 8 | -------------------------------------------------------------------------------- /docs/globals/juri.md: -------------------------------------------------------------------------------- 1 | ## juri 2 | 3 | This variable is a proxy of Uri::getInstance(). It allows to access the active URL as a Uri object inside twig layouts. 4 | 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Returns 9 | 10 | `Joomla\CMS\Uri\Uri` The active Uri instance. 11 | 12 | ### Examples 13 | 14 | ```twig 15 | {# Create a link to the home page #} 16 | Home 17 | ``` 18 | -------------------------------------------------------------------------------- /tests/tests/Module/Stubs/SampleTwigModule.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | array Variable casted 11 | 12 | ### Examples 13 | 14 | ```twig 15 | {# Create an array containing the active user id and dump the result #} 16 | {% raw %}{% set users = juser.get('id')|to_array %}{% endraw %} 17 | {% raw %}{{ dump(users) }}{% endraw %} 18 | ``` -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ./extensions 7 | */vendor/* 8 | */tests/* 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/globals/jdoc.md: -------------------------------------------------------------------------------- 1 | ## jdoc 2 | 3 | This variable is a proxy of Factory::getDocument(). It allows to access the active document inside twig layouts. 4 | 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Returns 9 | 10 | `\Joomla\CMS\Document\Document` The active document. 11 | 12 | ### Examples 13 | 14 | ```twig 15 | {% raw %} 16 | {# Load a script in this page from a twig layout #} 17 | {% do jdoc.addScriptDeclaration('alert("Hello world!")') %} 18 | {% endraw %} 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/globals/jsession.md: -------------------------------------------------------------------------------- 1 | ## jsession 2 | 3 | This variable is a proxy of Factory::getSession(). It allows to access the active session inside twig layouts. 4 | 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Returns 9 | 10 | `Joomla\CMS\Session\Session` The active session. 11 | 12 | ### Examples 13 | 14 | ```twig 15 | {# Retrieve a session token to use it in forms/urls #} 16 | Sample link with token 17 | ``` 18 | -------------------------------------------------------------------------------- /extensions/libraries/twig/form/field/viewlayout.php: -------------------------------------------------------------------------------- 1 | unserialize()" 8 | -------------------------------------------------------------------------------- /docs/globals/japp.md: -------------------------------------------------------------------------------- 1 | ## japp 2 | 3 | This variable is a proxy of Factory::getApplication(). It allows to access the active application inside twig layouts. 4 | 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Returns 9 | 10 | `\Joomla\CMS\Application\CMSApplication` The active application. 11 | 12 | ### Examples 13 | 14 | ```twig 15 | {# 16 | This will print something like: 17 | The active template is protostar 18 | #} 19 |
The active template is {% raw %}{{ japp.getTemplate() }}{% endraw %}
20 | ``` 21 | -------------------------------------------------------------------------------- /docs/globals/jlang.md: -------------------------------------------------------------------------------- 1 | ## jlang 2 | 3 | This variable is a proxy of Factory::getLanguage(). It allows to access the active language inside twig layouts. 4 | 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Returns 9 | 10 | `Joomla\CMS\Language\Language` The active language. 11 | 12 | ### Examples 13 | 14 | ```twig 15 | {# 16 | Use active language tag inside a layout. Will print something like: 17 | Active language is en-GB 18 | #} 19 |
{% raw %}Active language is {{ jlang.getTag() }}{% endraw %}
20 | ``` 21 | -------------------------------------------------------------------------------- /tests/tests/View/Traits/Stubs/ClassWithTwigRenderer.php: -------------------------------------------------------------------------------- 1 | $this]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | language: php 4 | 5 | addons: 6 | sonarcloud: 7 | organization: "phproberto-github" 8 | token: 9 | secure: "$SONAR_TOKEN" 10 | branches: 11 | - develop 12 | - master 13 | 14 | jdk: 15 | - oraclejdk8 16 | 17 | cache: 18 | directories: 19 | - ./build/node_modules 20 | - $HOME/.composer/cache/files 21 | - $HOME/.sonar/cache 22 | 23 | php: 24 | - 7.0 25 | - 7.1 26 | - 7.2 27 | 28 | branches: 29 | only: 30 | - master 31 | - develop 32 | 33 | before_script: 34 | - ./ci/setup.sh 35 | 36 | script: 37 | - ./ci/test.sh 38 | - sonar-scanner 39 | -------------------------------------------------------------------------------- /docs/globals/juser.md: -------------------------------------------------------------------------------- 1 | ## juser 2 | 3 | This variable is a proxy of Factory::getUser(). It allows to access the active user as a User object inside twig layouts. 4 | 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Returns 9 | 10 | `Joomla\CMS\User\User` The active User object. 11 | 12 | ### Examples 13 | 14 | ```twig 15 | {# Check if user is guest and say hello #} 16 | {% raw %}{% if juser.get('guest') %}{% endraw %} 17 | Hello guest! 18 | {% raw %}{% else %}{% endraw %} 19 | Hello {% raw %}{{ juser.get('name') }}{% endraw %}! 20 | {% raw %}{% endif %}{% endraw %} 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/functions/jposition.md: -------------------------------------------------------------------------------- 1 | ## jposition($position, $attribs = []) 2 | 3 | It allows to render a module position inside a twig layout. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$position** Name of the position to render 12 | * `array` **$attribs** An array of attributes for the module chrome function. 13 | 14 | ### Returns 15 | 16 | `string` HTML with the position content 17 | 18 | ### Examples 19 | 20 | ```twig 21 | {% raw %} 22 | {# Render the content of the template position-8 #} 23 | {{ jposition('position-8') }} 24 | {% endraw %} 25 | ``` 26 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Joomla Twig Package 5 | Twig integration for Joomla! 6 | pkg_twig 7 | package 8 | 1.5.0 9 | site 10 | https://github.com/phproberto/joomla-twig/releases/tag/v1.5.0 11 | 12 | https://github.com/phproberto/joomla-twig/releases/download/v1.5.0/joomla-twig-v1.5.0.zip 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | # must be unique in a given SonarQube instance 2 | sonar.projectKey=phproberto:joomla-twig 3 | # this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. 4 | sonar.projectName=joomla-twig 5 | sonar.projectVersion=1.4.0 6 | 7 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 8 | # This property is optional if sonar.modules is set. 9 | sonar.sources=./extensions/libraries/twig/src 10 | 11 | sonar.tests=./tests 12 | sonar.php.tests.reportPath=./tests/coverage/report-junit.xml 13 | sonar.php.coverage.reportPath=./tests/coverage/report-clover.xml 14 | 15 | # Encoding of the source code. Default is default system encoding 16 | sonar.sourceEncoding=UTF-8 17 | -------------------------------------------------------------------------------- /ci/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Clone current joomla & install composer there 4 | git clone https://github.com/joomla/joomla-cms.git /tmp/joomla-cms 5 | composer install -d /tmp/joomla-cms 6 | 7 | # Install joomla-twig testing composer dependencies 8 | composer install --prefer-dist --no-interaction --no-progress 9 | 10 | # Install joomla-twig library composer dependencies 11 | composer install -d ./extensions/libraries/twig 12 | 13 | # Copy CI gulp config (with cloned joomla path) to the build folder 14 | cp ./ci/gulp-config.ci.json ./build/gulp-config.json 15 | 16 | # Install npm packages in the build folder 17 | cd ./build 18 | npm install -g gulp 19 | npm install 20 | 21 | # Copy joomla extensions to the cloned joomla site 22 | gulp copy 23 | cd .. 24 | -------------------------------------------------------------------------------- /docs/functions/jlang.md: -------------------------------------------------------------------------------- 1 | ## jlang($key = null, $debug = false) 2 | 3 | This function is a proxy of `Language::getInstance()`. It allows to access HTML drawing classes inside twig layouts. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$lang** [optional] The language to use. Default: `en-GB` 12 | * `boolean` **$debug** [optional] The debug mode. Default: `false` 13 | 14 | ### Returns 15 | 16 | `\Joomla\CMS\Language\Language` Language object 17 | 18 | ### Examples 19 | 20 | ```twig 21 | {% raw %} 22 | {# Show the spanish language name #} 23 | {{ jlang('es-ES').getName() }} 24 | {% endraw %} 25 | ``` 26 | -------------------------------------------------------------------------------- /extensions/libraries/twig/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phproberto/joomla-twig", 3 | "type": "library", 4 | "description": "Twig integration for joomla", 5 | "keywords": ["joomla", "twig"], 6 | "homepage": "https://github.com/phproberto/joomla-twig", 7 | "license": "GPL-2.0", 8 | "authors": [ 9 | { 10 | "name": "Roberto Segura", 11 | "email": "roberto@phproberto.com", 12 | "homepage": "http://www.phproberto.com" 13 | } 14 | ], 15 | "require" : { 16 | "php": "^7.0", 17 | "twig/twig": "~2.0", 18 | "twig/extensions": "^1.4" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "Phproberto\\Joomla\\Twig\\": "src/" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /extensions/plugins/twig/japp/japp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JAPP 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JAPP_DESC 12 | 13 | language 14 | japp.php 15 | japp.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jdoc/jdoc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JDOC 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JDOC_DESC 12 | 13 | language 14 | jdoc.php 15 | jdoc.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/juri/juri.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JURI 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JURI_DESC 12 | 13 | language 14 | juri.php 15 | juri.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jhtml/jhtml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JHTML 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JHTML_DESC 12 | 13 | language 14 | jhtml.php 15 | jhtml.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jlang/jlang.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JLANG 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JLANG_DESC 12 | 13 | language 14 | jlang.php 15 | jlang.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jtext/jtext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JTEXT 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JTEXT_DESC 12 | 13 | language 14 | jtext.php 15 | jtext.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/juser/juser.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JUSER 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JUSER_DESC 12 | 13 | language 14 | juser.php 15 | juser.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/functions/jmodule_render_module.md: -------------------------------------------------------------------------------- 1 | ## jmodule_render_module($module, $attribs = array()) 2 | 3 | Render a module object. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `object` **$module** Object containing module information 12 | * `array` **$attribs** [optional] Array of attributes for the module (probably from the XML). 13 | 14 | ### Returns 15 | 16 | `\string` Rendered module. 17 | 18 | ### Examples 19 | 20 | ```twig 21 | {% raw %} 22 | {# Retrieve and display all the modules in a sidebar position #} 23 | {% for module in jmodule_get_modules('sidebar') %} 24 | {{ jmodule_render_module(module) }} 25 | {% endfor %} 26 | 27 | {% endraw %} 28 | ``` 29 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jarray/jarray.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JARRAY 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JARRAY_DESC 12 | 13 | language 14 | jarray.php 15 | jarray.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jroute/jroute.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JROUTE 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JROUTE_DESC 12 | 13 | language 14 | jroute.php 15 | jroute.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jlayout/jlayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JLAYOUT 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JLAYOUT_DESC 12 | 13 | language 14 | jlayout.php 15 | jlayout.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jmodule/jmodule.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JMODULE 4 | 1.0.0 5 | June 2018 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JMODULE_DESC 12 | 13 | language 14 | jmodule.php 15 | jmodule.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/View/ItemFormView.php: -------------------------------------------------------------------------------- 1 | $this->getModel()->getForm() 34 | ] 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/functions/jmodule_get_modules.md: -------------------------------------------------------------------------------- 1 | ## jmodule_get_modules($position) 2 | 3 | Gets modules assigned to a specific position. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$position** Name of the position 12 | 13 | ### Returns 14 | 15 | `array` An array containing modules of that position. Empty array if no modules were found. 16 | 17 | ### Examples 18 | 19 | ```twig 20 | {% raw %} 21 | {# Retrieve modules available in a `sidebar` position #} 22 | {% set modules = jmodule_get_modules('sidebar') %} 23 | {% for module in modules %} 24 |
Found module: {{ module.name }} with title: {{ module.title }}
25 | {% endfor %} 26 | 27 | {% endraw %} 28 | ``` 29 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jregistry/jregistry.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JREGISTRY 4 | 1.0.0 5 | June 2018 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JREGISTRY_DESC 12 | 13 | language 14 | jregistry.php 15 | jregistry.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jsession/jsession.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JSESSION 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JSESSION_DESC 12 | 13 | language 14 | jsession.php 15 | jsession.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jposition/jposition.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JPOSITION 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JPOSITION_DESC 12 | 13 | language 14 | jposition.php 15 | jposition.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jprofiler/jprofiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_JPROFILER 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_JPROFILER_DESC 12 | 13 | language 14 | jprofiler.php 15 | jprofiler.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/unserialize/unserialize.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_UNSERIALIZE 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_UNSERIALIZE_DESC 12 | 13 | language 14 | unserialize.php 15 | unserialize.xml 16 | 17 | 18 | -------------------------------------------------------------------------------- /extensions/plugins/twig/cache/language/en-GB/en-GB.plg_twig_cache.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_cache 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_CACHE="Twig - Cache" 7 | PLG_TWIG_CACHE_DESC="Enables cache for twig" 8 | 9 | PLG_TWIG_CACHE_PARAM_ENABLED="Enable" 10 | PLG_TWIG_CACHE_PARAM_ENABLED_DESC="Do you want to enable the cache system? Using global will enable it when Joomla! cache is enabled." 11 | PLG_TWIG_CACHE_PARAM_ENABLED_OPTION_GLOBAL="-- Use global --" 12 | PLG_TWIG_CACHE_PARAM_MODE="Cache status" 13 | PLG_TWIG_CACHE_PARAM_MODE_DESC="Here you can enable/disable Twig cache." 14 | PLG_TWIG_CACHE_PARAM_MODE_OPTION_ENABLED="Enabled" 15 | PLG_TWIG_CACHE_PARAM_MODE_OPTION_DISABLED="Disabled" 16 | -------------------------------------------------------------------------------- /ci/phpunit.ci.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ../tests 10 | 11 | 12 | 13 | 15 | 18 | 19 | 20 | 21 | ../extensions/libraries/twig/src 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/View/FormView.php: -------------------------------------------------------------------------------- 1 | getModel(); 31 | 32 | return array_merge( 33 | parent::loadLayoutData(), 34 | [ 35 | 'form' => $model->getForm(), 36 | 'model' => $model 37 | ] 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/View/ItemView.php: -------------------------------------------------------------------------------- 1 | getModel(); 31 | 32 | return array_merge( 33 | parent::loadLayoutData(), 34 | [ 35 | 'item' => $model->getItem(), 36 | 'model' => $model 37 | ] 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /extensions/plugins/twig/debug/language/en-GB/en-GB.plg_twig_debug.sys.ini: -------------------------------------------------------------------------------- 1 | ; plg_twig_debug 2 | ; Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE 4 | ; Note : All ini files need to be saved as UTF-8 5 | 6 | PLG_TWIG_DEBUG="Twig - Debug" 7 | PLG_TWIG_DEBUG_DESC="Enables debug mode and dump function in twig" 8 | 9 | PLG_TWIG_DEBUG_PARAM_MODE="Enable debug" 10 | PLG_TWIG_DEBUG_PARAM_MODE_DESC="Select the method to enable debug in twig:
Automatically: use joomla debug status.
Always: use debug even if joomla debug is disabled.
Never: disable debug even if joomla debug is enabled." 11 | PLG_TWIG_DEBUG_PARAM_MODE_OPTION_AUTO="Automatically" 12 | PLG_TWIG_DEBUG_PARAM_MODE_OPTION_ALWAYS="Always" 13 | PLG_TWIG_DEBUG_PARAM_MODE_OPTION_NEVER="Never" 14 | -------------------------------------------------------------------------------- /docs/functions/jregistry.md: -------------------------------------------------------------------------------- 1 | ## jregistry($data = null) 2 | 3 | This function returns an instance of `Joomla\Registry\Registry::getInstance()`. It allows to handle data coming from extension params or to create setting objects with defaults. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `mixed` **$data** JSON string | Array. 12 | 13 | ### Returns 14 | 15 | `Joomla\Registry\Registry` A registry instance. 16 | 17 | ### Examples 18 | 19 | ```twig 20 | {% raw %} 21 | {# Create a registry object from module parameters #} 22 | {% set params = jregistry(module.params) %} 23 | 24 | {% if params.get('format') === 'short' %} 25 |
Short format selected in module params
26 | {% endif %} 27 | 28 | {% endraw %} 29 | ``` 30 | -------------------------------------------------------------------------------- /extensions/libraries/twig/twig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Twig - Library 4 | twig 5 | September 2018 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | 1.5.0 12 | Twig library 13 | 14 | form 15 | language 16 | layouts 17 | src 18 | vendor 19 | library.php 20 | 21 | 22 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/View/HtmlView.php: -------------------------------------------------------------------------------- 1 | $this 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/filters/unserialize.md: -------------------------------------------------------------------------------- 1 | ## unserialize 2 | 3 | Filter to unserialize a variable. Equivalent to PHP's [`unserialize($variable)`](http://php.net/manual/en/function.unserialize.php) 4 | 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Returns 9 | 10 | The converted value is returned, and can be a boolean, integer, float, string, array or object. 11 | 12 | In case the passed string is not unserializeable, FALSE is returned and E_NOTICE is issued. 13 | 14 | ### Examples 15 | 16 | ```twig 17 | {# If you have serialized a variable in session you can recover it and unserialize it in twig #} 18 | {% raw %}{% set cartItems = jsession.get('cartItems', []) %}{% endraw %} 19 | {% raw %}{% if cartItems is not iterable %}{% endraw %} 20 | {% raw %}{% set cartItems = cartItems|unserialize %}{% endraw %} 21 | {% raw %}{% endif %}{% endraw %} 22 | ``` -------------------------------------------------------------------------------- /docs/functions/jhtml.md: -------------------------------------------------------------------------------- 1 | ## jhtml($key, $...) 2 | 3 | This function is a proxy of `HTMLHelper::_($key)`. It allows to access HTML drawing classes inside twig layouts. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$key** The name of helper method to load, (prefix).(class).function prefix and class are optional and can be used to load custom html helpers. 12 | * `mixed` **$...** Optional parameters for the helper method. 13 | 14 | ### Returns 15 | 16 | `mixed` Result of HTMLHelper::call($function, $args) 17 | 18 | ### Examples 19 | 20 | ```twig 21 | {% raw %} 22 | {# Render a form token. It will render something like: 23 | #} 24 | {{ jhtml('form.token') }} 25 | {% endraw %} 26 | ``` 27 | -------------------------------------------------------------------------------- /phpunit.dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ./tests 10 | 11 | 12 | 13 | 15 | 17 | 20 | 21 | 22 | 23 | ./extensions/libraries/twig/src 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/functions/jtext_sprintf.md: -------------------------------------------------------------------------------- 1 | ## jtext_sprintf($string, $...) 2 | 3 | This function is a proxy of `Joomla\CMS\Language\Text::sprintf()`. It allows to use translatable strings inside twig layouts. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$string** The format string. 12 | * `mixed` **$...** Replacements for string parts. 13 | 14 | ### Returns 15 | 16 | `string` The translated strings or the key if 'script' is true in the array of options. 17 | 18 | ### Examples 19 | 20 | ```twig 21 | {% raw %} 22 | {# Display the translation of the JNEXT_TITLE language string (which would be something like "Next article: %s"). It will show something like: 23 | Next article: My article title 24 | #} 25 | {{ jtext_sprintf('JNEXT_TITLE', 'My article title') }} 26 | {% endraw %} 27 | ``` 28 | -------------------------------------------------------------------------------- /tests/tests/Plugin/Stubs/SamplePlugin.php: -------------------------------------------------------------------------------- 1 | autoloadLanguage = true; 28 | 29 | $config = array(); 30 | $config['name'] = 'Sample'; 31 | $config['type'] = 'System'; 32 | $config['params'] = new Registry; 33 | 34 | $dispatcher = \JEventDispatcher::getInstance(); 35 | 36 | // Call the parent constructor 37 | parent::__construct($dispatcher, $config); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/Unserialize.php: -------------------------------------------------------------------------------- 1 | addGlobal('japp', Factory::getApplication()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jdoc/jdoc.php: -------------------------------------------------------------------------------- 1 | addGlobal('jdoc', Factory::getDocument()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JUri.php: -------------------------------------------------------------------------------- 1 | addExtension(new JHtml); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jtext/jtext.php: -------------------------------------------------------------------------------- 1 | addExtension(new JText); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/functions/juser.md: -------------------------------------------------------------------------------- 1 | ## juser($id = null) 2 | 3 | This function is a proxy of `Joomla\CMS\Factory::getUser()`. It allows to retrieve users to use them inside twig layouts. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `integer` **$id** [optional] User to load. Default: use active user 12 | 13 | ### Returns 14 | 15 | `Joomla\CMS\User\User` The User object. 16 | 17 | ### Examples 18 | 19 | ```twig 20 | {% raw %} 21 | {# Retrieve active user not using any id. This is not usually required because you can already use `juser` global var #} 22 | {% set activeUser = juser() %} 23 | 24 | {# Retrieve the user with id: 668 #} 25 | {% set user = juser(668) %} 26 | 27 | {# Let's test if user was found #} 28 | {% if user.get('guest') %} 29 | User could not be loaded 30 | {% else %} 31 | User found with email: {{ user.email }} 32 | {% endif %} 33 | {% endraw %} 34 | ``` 35 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JUser.php: -------------------------------------------------------------------------------- 1 | addExtension(new JArray); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JRoute.php: -------------------------------------------------------------------------------- 1 | addExtension(new JRoute); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jlayout/jlayout.php: -------------------------------------------------------------------------------- 1 | addExtension(new JLayout); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jposition/jposition.php: -------------------------------------------------------------------------------- 1 | addExtension(new JPosition); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JSession.php: -------------------------------------------------------------------------------- 1 | addExtension(new Unserialize); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jprofiler/jprofiler.php: -------------------------------------------------------------------------------- 1 | addExtension(new JProfiler); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jregistry/jregistry.php: -------------------------------------------------------------------------------- 1 | addExtension(new JRegistry); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JLanguage.php: -------------------------------------------------------------------------------- 1 | addExtension(new JModuleHelper); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JProfiler.php: -------------------------------------------------------------------------------- 1 | pluginPath) 38 | { 39 | $reflection = new \ReflectionClass($this); 40 | 41 | $this->pluginPath = dirname($reflection->getFileName()); 42 | } 43 | 44 | return $this->pluginPath; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /extensions/libraries/twig/library.php: -------------------------------------------------------------------------------- 1 | load('lib_twig', __DIR__); 37 | 38 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JText.php: -------------------------------------------------------------------------------- 1 | getModel(); 31 | 32 | return array_merge( 33 | parent::loadLayoutData(), 34 | [ 35 | 'items' => $model->getItems(), 36 | 'state' => $model->getState(), 37 | 'pagination' => $model->getPagination(), 38 | 'filterForm' => $model->getFilterForm(), 39 | 'activeFilters' => $model->getActiveFilters(), 40 | 'model' => $model 41 | ] 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /extensions/plugins/twig/juri/juri.php: -------------------------------------------------------------------------------- 1 | addExtension(new JUri); 37 | $environment->addGlobal('juri', Uri::getInstance()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/functions/jlayout_render.md: -------------------------------------------------------------------------------- 1 | ## jlayout_render($layoutFile, $displayData = null, $basePath = '', $options = null) 2 | 3 | Fast rendering of JLayout files inside a twig layouts. Proxy of `\Joomla\CMS\LayoutHelper::render()`. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$layoutFile** Dot separated path to the layout file, relative to base path. 12 | * `mixed` **$displayData** [optional] Array|Object which the data for the layout file. Default: `null` 13 | * `string` **$basePath** [optional] Base path to use when loading layout files. 14 | * `mixed` **$options** [optional] Custom options to load. Registry or array format 15 | 16 | ### Returns 17 | 18 | `string` HTML with layout output 19 | 20 | ### Examples 21 | 22 | ```twig 23 | {% raw %} 24 | {# Render the joomla.html.treeprefix layout with ['level' => 10] as data #} 25 | {{ jlayout_render('joomla.html.treeprefix', {'level' : 10}) }} 26 | {% endraw %} 27 | ``` 28 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JHtml.php: -------------------------------------------------------------------------------- 1 | ['html'] 34 | ]; 35 | 36 | return [ 37 | new TwigFunction('jhtml', [HTMLHelper::class, '_'], $options) 38 | ]; 39 | } 40 | 41 | /** 42 | * Get the name of this extension. 43 | * 44 | * @return string 45 | */ 46 | public function getName() : string 47 | { 48 | return 'jhtml'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Traits/HasLayoutData.php: -------------------------------------------------------------------------------- 1 | layoutData[__CLASS__])) 36 | { 37 | $this->layoutData[__CLASS__] = $this->loadLayoutData(); 38 | } 39 | 40 | return $this->layoutData[__CLASS__]; 41 | } 42 | 43 | /** 44 | * Load layout data. 45 | * 46 | * @return array 47 | */ 48 | abstract protected function loadLayoutData(); 49 | } 50 | -------------------------------------------------------------------------------- /extensions/plugins/twig/juser/juser.php: -------------------------------------------------------------------------------- 1 | addExtension(new JUser); 37 | $environment->addGlobal('juser', Factory::getUser()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/tests/Loader/TemplateLoaderTest.php: -------------------------------------------------------------------------------- 1 | getMethod('getTemplatePaths'); 32 | $method->setAccessible(true); 33 | 34 | $expected = [ 35 | JPATH_BASE . '/templates/' . \JFactory::getApplication()->getTemplate() . '/html' 36 | ]; 37 | 38 | $this->assertSame($expected, $method->invoke($loader)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docs/functions/jlayout_debug.md: -------------------------------------------------------------------------------- 1 | ## jlayout_debug($layoutFile, $displayData = null, $basePath = '', $options = null) 2 | 3 | Fast debug of JLayout files rendering inside a twig layouts. Proxy of `\Joomla\CMS\LayoutHelper::debug()`. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$layoutFile** Dot separated path to the layout file, relative to base path. 12 | * `mixed` **$displayData** [optional] Array|Object which the data for the layout file. Default: `null` 13 | * `string` **$basePath** [optional] Base path to use when loading layout files. 14 | * `mixed` **$options** [optional] Custom options to load. Registry or array format 15 | 16 | ### Returns 17 | 18 | `string` HTML with layout output + debug info 19 | 20 | ### Examples 21 | 22 | ```twig 23 | {% raw %} 24 | {# Debug the joomla.html.treeprefix layout with ['level' => 10] as data #} 25 | {{ jlayout_debug('joomla.html.treeprefix', {'level' : 10}) }} 26 | {% endraw %} 27 | ``` 28 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jlang/jlang.php: -------------------------------------------------------------------------------- 1 | addExtension(new JLanguage); 37 | $environment->addGlobal('jlang', Factory::getLanguage()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Loader/TemplateLoader.php: -------------------------------------------------------------------------------- 1 | getTemplate() . '/html'; 40 | 41 | if (is_dir($tplOverrides)) 42 | { 43 | $paths[] = $tplOverrides; 44 | } 45 | 46 | return $paths; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /docs/functions/jroute.md: -------------------------------------------------------------------------------- 1 | ## jroute($url, $xhtml = true, $ssl = null) 2 | 3 | This function is a proxy of `Joomla\CMS\Router\Route::_()`. It allows to build SEF urls inside twig layouts. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$url** Absolute or Relative URI to Joomla resource. 12 | * `boolean` **$xhtml** Replace & by & for XML compliance. 13 | * `integer` **$ssl** Secure state for the resolved URI. 14 | * 0: (default) No change, use the protocol currently used in the request 15 | * 1: Make URI secure using global secure site URI. 16 | * 2: Make URI unsecure using the global unsecure site URI. 17 | 18 | ### Returns 19 | 20 | `string` The translated humanly readable URL. 21 | 22 | ### Examples 23 | 24 | ```twig 25 | {% raw %} 26 | {# Load a profiler and mark to points before and after doing something #} 27 | View category 28 | {% endraw %} 29 | ``` 30 | -------------------------------------------------------------------------------- /extensions/plugins/twig/jsession/jsession.php: -------------------------------------------------------------------------------- 1 | addExtension(new JSession); 37 | $environment->addGlobal('jsession', Factory::getSession()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/functions/jtext.md: -------------------------------------------------------------------------------- 1 | ## jtext($string, $jsSafe = false, $interpretBackSlashes = true, $script = false) 2 | 3 | This function is a proxy of `Joomla\CMS\Language\Text::_()`. It allows to use translatable strings inside twig layouts. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$string** The string to translate. 12 | * `mixed` **$jsSafe** Boolean: Make the result javascript safe. 13 | * `boolean` **$interpretBackSlashes** To interpret backslashes (\\=\, \n=carriage return, \t=tabulation). 14 | * `boolean` **$script** To indicate that the string will be push in the javascript language store: 15 | 16 | ### Returns 17 | 18 | `string` The translated string or the key if $script is true. 19 | 20 | ### Examples 21 | 22 | ```twig 23 | {% raw %} 24 | {# Display the translation of the JENABLED language string. It will display something like: 25 | "Something is enabled" #} 26 | Something is {{ jtext('JENABLED') }} 27 | {% endraw %} 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/functions/juri.md: -------------------------------------------------------------------------------- 1 | ## juri($uri = 'SERVER') 2 | 3 | This function is a proxy of `Joomla\CMS\Uri\Uri::getInstance()`. It allows to deal with URLs as objects inside twig layouts. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$uri** [optional] The URI to parse. Default: active URL 12 | 13 | ### Returns 14 | 15 | `Joomla\CMS\Uri\Uri` The Uri object. 16 | 17 | ### Examples 18 | 19 | ```twig 20 | {% raw %} 21 | {# Load a URL into a uri object. Add Itemid=1976, remove view=category and finally ouput it as string #} 22 | {% set uri = juri('index.php?option=com_content&view=category') %} 23 | 24 | {# Add Itemid=1976 to the uri #} 25 | {% do uri.setVar('Itemid', 1976) %} 26 | 27 | {# Remove view=category from the uri #} 28 | {% do uri.delVar('view') %} 29 | 30 | {# Print final URL #} 31 |
Final URL is: {{ uri.toString() }}
32 | 33 | {# This will also print the url because Uri implements `__toString()` magic method #} 34 |
Final URL is: {{ uri }}
35 | {% endraw %} 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/functions/jmodule_get_module.md: -------------------------------------------------------------------------------- 1 | ## jmodule_get_module($name, $title = null) 2 | 3 | Get a module published on the current page by its name or folder. 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$name** Name of the module (real, eg 'Breadcrumbs' or folder, eg 'mod_breadcrumbs') 12 | * `array` **$title** [optional] Title of the module. 13 | 14 | ### Returns 15 | 16 | `\stdClass|null` - The first module found that matches the name if found. Empty object if module not found and name starts with `mod_`. Null otherwise. 17 | 18 | ### Examples 19 | 20 | ```twig 21 | {% raw %} 22 | {# Retrieve a `mod_menu` module #} 23 | {% set module = jmodule_get_module('mod_menu') %} 24 | 25 | {# Retrieve a `mod_menu` module by its name (name is the module element removing the mod_ part). #} 26 | {% set module = jmodule_get_module('menu') %} 27 | 28 | {# Retrieve a `mod_menu` module with a specific title. #} 29 | {% set module = jmodule_get_module('mod_menu', 'Main Menu') %} 30 | 31 | {% endraw %} 32 | ``` 33 | -------------------------------------------------------------------------------- /tests/tests/Field/Stubs/SampleField.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/tmpl', 37 | 'Unexisting' => __DIR__ . '/unexisting' 38 | ]; 39 | } 40 | 41 | /** 42 | * Load available option groups 43 | * 44 | * @return array 45 | */ 46 | protected function loadGroups() : array 47 | { 48 | return $this->loadGroups ?: parent::loadGroups(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /docs/functions/jprofiler.md: -------------------------------------------------------------------------------- 1 | ## jprofiler($prefix = '') 2 | 3 | This function is a proxy of `Joomla\CMS\Profiler\Profiler::getInstance()`. It allows to use a profiler to debug performance inside twig layouts. 4 | 1. [Parameters](#parameters) 5 | 1. [Returns](#returns) 6 | 2. [Examples](#examples) 7 | 8 | ### Parameters 9 | 10 | * `string` **$prefix** Prefix used to distinguish profiler objects. 11 | 12 | ### Returns 13 | 14 | `Joomla\CMS\Profiler\Profiler` A profiler instance. 15 | 16 | ### Examples 17 | 18 | ```twig 19 | {% raw %} 20 | {# Load a custom profiler with twig prefix. Best of jprofiler is that you can share profilers from PHP & twig to fully trace performance issues. #} 21 | {% set profiler = jprofiler('twig') %} 22 | 23 | {# echo memory & time consumed before doing something. If you want to hide in production while debugging an issue this you can use display: hidden in the container #} 24 |
{{ profiler.mark('before loading something') }}
25 | 26 | {# Here what you want to debug #} 27 | 28 | {# echo memory & time consumed after something. #} 29 |
{{ profiler.mark('after loading something') }}
30 | {% endraw %} 31 | ``` 32 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Traits/HasTwigRenderer.php: -------------------------------------------------------------------------------- 1 | getRenderer()->render($layout, array_merge($this->getLayoutData(), $data)); 40 | } 41 | 42 | /** 43 | * Get the module renderer. 44 | * 45 | * @return Twig 46 | */ 47 | public function getRenderer() : Twig 48 | { 49 | return Twig::instance(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phproberto/joomla-twig", 3 | "description": "Twig 2.0 integration for Joomla!", 4 | "license": "GPL-2.0", 5 | "authors": [ 6 | { 7 | "name": "Roberto Segura López", 8 | "email": "roberto@phproberto.com", 9 | "homepage": "http://phproberto.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^7.0" 14 | }, 15 | "autoload": { 16 | "psr-4": { 17 | "Phproberto\\Joomla\\Twig\\": "extensions/libraries/twig/src/" 18 | } 19 | }, 20 | "autoload-dev": { 21 | "psr-4": { 22 | "Phproberto\\Joomla\\Twig\\Tests\\": "tests/tests" 23 | } 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "^4.8.35", 27 | "joomla/coding-standards": "~2.0@alpha", 28 | "squizlabs/php_codesniffer": "^2.8" 29 | }, 30 | "scripts": { 31 | "clean": "cd ./build && gulp clean", 32 | "copy" : "cd ./build && gulp copy", 33 | "cs" : "./vendor/bin/phpcs", 34 | "dev": "cd ./build && gulp", 35 | "release" : "cd ./build && gulp release", 36 | "setup" : "cd ./build && npm install && cp gulp-config.dist.json gulp-config.json", 37 | "test" : "./vendor/bin/phpunit", 38 | "watch" : "cd ./build && gulp watch" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docs/functions/jlayout.md: -------------------------------------------------------------------------------- 1 | ## jlayout($layoutId, $basePath = null, $options = null) 2 | 3 | Create an instance of `\Joomla\CMS\Layout\FileLayout` to use it inside a twig layout . 4 | 5 | 1. [Parameters](#parameters) 6 | 1. [Returns](#returns) 7 | 2. [Examples](#examples) 8 | 9 | ### Parameters 10 | 11 | * `string` **$layoutId** Dot separated path to the layout file, relative to base path. 12 | * `string` **$basePath** [optional] Base path to use when loading layout files. 13 | * `mixed` **$options** [optional] Custom options to load. Registry or array format. 14 | 15 | ### Returns 16 | 17 | `\Joomla\CMS\Layout\FileLayout` FileLayout instance. 18 | 19 | ### Examples 20 | 21 | ```twig 22 | {% raw %} 23 | {# Create a layout instance of `joomla.system.message` to render some dynamically generated messages #} 24 | {% set data = { 25 | 'msgList' : { 26 | 'error' : [ 27 | 'Something went wrong. Ask help to @mbabker', 28 | 'Still broken. Contact OSM?' 29 | ], 30 | 'info' : [ 31 | 'Using Twig inside Joomla! is cool' 32 | ] 33 | } 34 | } 35 | %} 36 | {% set layout = jlayout('joomla.system.message') %} 37 | {{ layout.render(data)|raw }} 38 | {% endraw %} 39 | ``` 40 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JArray.php: -------------------------------------------------------------------------------- 1 | ['html']]) 38 | ]; 39 | } 40 | 41 | /** 42 | * Get the name of this extension. 43 | * 44 | * @return string 45 | */ 46 | public function getName() : string 47 | { 48 | return 'jmodule'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /extensions/plugins/twig/cache/cache.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_CACHE 4 | 1.1.0 5 | September 2018 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_CACHE_DESC 12 | 13 | language 14 | cache.php 15 | cache.xml 16 | 17 | 18 | 19 |
20 | 28 | 29 | 30 | 31 | 32 |
33 |
34 |
35 |
36 | -------------------------------------------------------------------------------- /extensions/plugins/twig/debug/debug.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PLG_TWIG_DEBUG 4 | 1.0.0 5 | October 2017 6 | Roberto Segura 7 | roberto@phproberto.com 8 | www.phproberto.com 9 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 10 | GNU General Public License version 2 or later, see LICENSE. 11 | PLG_TWIG_DEBUG_DESC 12 | 13 | language 14 | debug.php 15 | debug.xml 16 | 17 | 18 | 19 |
20 | 27 | 28 | 29 | 30 | 31 |
32 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /tests/tests/Loader/Stubs/SampleLoader.php: -------------------------------------------------------------------------------- 1 | parsedExtensionName ?: parent::parseExtensionName($name); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JLayout.php: -------------------------------------------------------------------------------- 1 | ['html'] 35 | ]; 36 | 37 | return [ 38 | new TwigFunction('jlayout', [$this, 'getFileLayout']), 39 | new TwigFunction('jlayout_render', [LayoutHelper::class, 'render'], $options), 40 | new TwigFunction('jlayout_debug', [LayoutHelper::class, 'debug'], $options) 41 | ]; 42 | } 43 | 44 | /** 45 | * Retrive a FileLayout instance. 46 | * 47 | * @return FileLayout 48 | */ 49 | public function getFileLayout() : FileLayout 50 | { 51 | $class = new \ReflectionClass(FileLayout::class); 52 | 53 | return $class->newInstanceArgs(func_get_args()); 54 | } 55 | 56 | /** 57 | * Get the name of this extension. 58 | * 59 | * @return string 60 | */ 61 | public function getName() : string 62 | { 63 | return 'jlayout'; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/tests/Mock/TwigMock.php: -------------------------------------------------------------------------------- 1 | getProperty('environment'); 38 | $environmentProperty->setAccessible(true); 39 | $environmentProperty->setValue($twig, new Environment($loader)); 40 | 41 | return $twig; 42 | } 43 | 44 | /** 45 | * Persist a twig so it's server by Twig:instance 46 | * 47 | * @param Twig $twig Twig instance to persist 48 | * 49 | * @return void 50 | */ 51 | public static function setInstance(Twig $twig) 52 | { 53 | $reflection = new \ReflectionClass(Twig::class); 54 | 55 | $instanceProperty = $reflection->getProperty('instance'); 56 | $instanceProperty->setAccessible(true); 57 | $instanceProperty->setValue(Twig::class, $twig); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/tests/Extension/UnerializeTest.php: -------------------------------------------------------------------------------- 1 | extension = new Unserialize; 34 | } 35 | 36 | /** 37 | * Test getFilters returns correct data. 38 | * 39 | * @return void 40 | */ 41 | public function testGetFiltersReturnsCorrectData() 42 | { 43 | $this->assertEquals(1, count($this->extension->getFilters())); 44 | 45 | $filter = $this->extension->getFilters()[0]; 46 | 47 | $callable = $filter->getCallable(); 48 | $this->assertTrue(is_callable($callable)); 49 | $this->assertEquals('unserialize', $filter->getName()); 50 | $this->assertEquals('unserialize', $callable); 51 | } 52 | 53 | /** 54 | * getName returns correct extension name. 55 | * 56 | * @return void 57 | */ 58 | public function testGetNameReturnsJapp() 59 | { 60 | $this->assertEquals('junserialize', $this->extension->getName()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/tests/Extension/JUriTest.php: -------------------------------------------------------------------------------- 1 | extension = new JUri; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctions() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('juri', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'juri' => [ 68 | 'class' => Uri::class, 69 | 'method' => 'getInstance' 70 | ] 71 | ]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/tests/Extension/JUserTest.php: -------------------------------------------------------------------------------- 1 | extension = new JUser; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctions() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('juser', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'juser' => [ 68 | 'class' => Factory::class, 69 | 'method' => 'getUser' 70 | ] 71 | ]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/tests/Extension/JRouteTest.php: -------------------------------------------------------------------------------- 1 | extension = new JRoute; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctions() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('jroute', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'jroute' => [ 68 | 'class' => Route::class, 69 | 'method' => '_' 70 | ] 71 | ]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/tests/Extension/Traits/HasFunctions.php: -------------------------------------------------------------------------------- 1 | expectedFunctions(); 28 | $functions = $this->extension->getFunctions(); 29 | 30 | $this->assertEquals(count($expectedFunctions), count($functions)); 31 | 32 | foreach ($functions as $function) 33 | { 34 | $callable = $function->getCallable(); 35 | $functionName = $function->getName(); 36 | 37 | $this->assertTrue(array_key_exists($functionName, $expectedFunctions)); 38 | 39 | $expectedFunction = $expectedFunctions[$functionName]; 40 | 41 | $callableClass = is_string($callable[0]) ? $callable[0] : get_class($callable[0]); 42 | $callableMethod = $callable[1]; 43 | 44 | $this->assertTrue(is_callable($callable)); 45 | 46 | $this->assertEquals($expectedFunction['class'], $callableClass); 47 | $this->assertEquals($expectedFunction['method'], $callableMethod); 48 | } 49 | } 50 | 51 | /** 52 | * Functions expected to be added by the extension. 53 | * 54 | * @return array 55 | */ 56 | abstract protected function expectedFunctions(); 57 | } 58 | -------------------------------------------------------------------------------- /tests/tests/Extension/JHtmlTest.php: -------------------------------------------------------------------------------- 1 | extension = new JHtml; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctionsReturnsCorrectData() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('jhtml', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'jhtml' => [ 68 | 'class' => HTMLHelper::class, 69 | 'method' => '_' 70 | ] 71 | ]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Loader/LibraryLoader.php: -------------------------------------------------------------------------------- 1 | getTemplate() . '/html/libraries'; 40 | 41 | if (is_dir($tplOverrides)) 42 | { 43 | $paths[] = $tplOverrides; 44 | } 45 | 46 | $paths[] = JPATH_LIBRARIES; 47 | 48 | return $paths; 49 | } 50 | 51 | /** 52 | * Parse a received extension name. 53 | * 54 | * @param string $name Name of the template to search 55 | * 56 | * @return string 57 | */ 58 | protected function parseExtensionName(string $name) : string 59 | { 60 | $nameParts = explode('/', $name); 61 | 62 | if (!isset($nameParts[1])) 63 | { 64 | return $name; 65 | } 66 | 67 | array_splice($nameParts, 1, 1, [$nameParts[1], 'layouts']); 68 | 69 | return implode('/', $nameParts); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Loader/PluginLoader.php: -------------------------------------------------------------------------------- 1 | getTemplate() . '/html/plugins'; 40 | 41 | if (is_dir($tplOverrides)) 42 | { 43 | $paths[] = $tplOverrides; 44 | } 45 | 46 | $paths[] = JPATH_SITE . '/plugins'; 47 | 48 | return $paths; 49 | } 50 | 51 | /** 52 | * Parse a received extension name. 53 | * 54 | * @param string $name Name of the template to search 55 | * 56 | * @return string 57 | */ 58 | protected function parseExtensionName(string $name) : string 59 | { 60 | $nameParts = explode('/', $name); 61 | 62 | if (!isset($nameParts[2])) 63 | { 64 | return $name; 65 | } 66 | 67 | array_splice($nameParts, 2, 1, [$nameParts[2], 'tmpl']); 68 | 69 | return implode('/', $nameParts); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/tests/Extension/JSessionTest.php: -------------------------------------------------------------------------------- 1 | extension = new JSession; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctions() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('jsession', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'jsession' => [ 68 | 'class' => Factory::class, 69 | 'method' => 'getSession' 70 | ] 71 | ]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Loader/ModuleLoader.php: -------------------------------------------------------------------------------- 1 | getTemplate() . '/html'; 40 | 41 | if (is_dir($tplOverrides)) 42 | { 43 | $paths[] = $tplOverrides; 44 | } 45 | 46 | $paths[] = $this->getBaseAppPath() . '/modules'; 47 | 48 | return $paths; 49 | } 50 | 51 | /** 52 | * Parse a received extension name. 53 | * 54 | * @param string $name Name of the template to search 55 | * 56 | * @return string 57 | */ 58 | protected function parseExtensionName(string $name) : string 59 | { 60 | $nameParts = explode('/', $name); 61 | 62 | if (!isset($nameParts[1])) 63 | { 64 | return $name; 65 | } 66 | 67 | array_splice($nameParts, 1, 1, [$nameParts[1], 'tmpl']); 68 | 69 | return implode('/', $nameParts); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/tests/Extension/JProfilerTest.php: -------------------------------------------------------------------------------- 1 | extension = new JProfiler; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctions() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('jprofiler', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'jprofiler' => [ 68 | 'class' => Profiler::class, 69 | 'method' => 'getInstance' 70 | ] 71 | ]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Loader/ComponentLoader.php: -------------------------------------------------------------------------------- 1 | getTemplate() . '/html'; 40 | 41 | if (is_dir($tplOverrides)) 42 | { 43 | $paths[] = $tplOverrides; 44 | } 45 | 46 | $paths[] = $this->getBaseAppPath() . '/components'; 47 | 48 | return $paths; 49 | } 50 | 51 | /** 52 | * Parse a received extension name. 53 | * 54 | * @param string $name Name of the template to search 55 | * 56 | * @return string 57 | */ 58 | protected function parseExtensionName(string $name) : string 59 | { 60 | $nameParts = explode('/', $name); 61 | 62 | if (!isset($nameParts[2])) 63 | { 64 | return $name; 65 | } 66 | 67 | array_splice($nameParts, 2, 1, ['views', $nameParts[2], 'tmpl']); 68 | 69 | return implode('/', $nameParts); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/tests/Plugin/BasePluginTest.php: -------------------------------------------------------------------------------- 1 | saveFactoryState(); 31 | 32 | \JFactory::$config = $this->getMockConfig(); 33 | \JFactory::$application = $this->getMockCmsApp(); 34 | } 35 | 36 | /** 37 | * Tears down the fixture, for example, closes a network connection. 38 | * This method is called after a test is executed. 39 | * 40 | * @return void 41 | */ 42 | protected function tearDown() 43 | { 44 | $this->restoreFactoryState(); 45 | parent::tearDown(); 46 | } 47 | 48 | /** 49 | * pluginPath returns correct path. 50 | * 51 | * @return void 52 | */ 53 | public function testPluginPathReturnsCorrectPath() 54 | { 55 | $plugin = new SamplePlugin; 56 | 57 | $reflection = new \ReflectionClass($plugin); 58 | $method = $reflection->getMethod('pluginPath'); 59 | $method->setAccessible(true); 60 | 61 | $this->assertSame(__DIR__ . '/Stubs', $method->invoke($plugin)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/tests/Extension/Traits/HasFilters.php: -------------------------------------------------------------------------------- 1 | expectedFilters(); 28 | $filters = $this->extension->getFilters(); 29 | 30 | $this->assertEquals(count($expectedFilters), count($filters)); 31 | 32 | foreach ($filters as $filter) 33 | { 34 | $callable = $filter->getCallable(); 35 | $filterName = $filter->getName(); 36 | 37 | $this->assertTrue(array_key_exists($filterName, $expectedFilters)); 38 | 39 | $expectedFilter = $expectedFilters[$filterName]; 40 | 41 | $callableClass = null; 42 | $callableMethod = $callable; 43 | 44 | if (is_array($callable)) 45 | { 46 | $callableClass = is_string($callable[0]) ? $callable[0] : get_class($callable[0]); 47 | $callableMethod = $callable[1]; 48 | } 49 | 50 | $this->assertTrue(is_callable($callable)); 51 | 52 | $this->assertEquals($expectedFilter['class'], $callableClass); 53 | $this->assertEquals($expectedFilter['method'], $callableMethod); 54 | } 55 | } 56 | 57 | /** 58 | * Filters expected to be added by the extension. 59 | * 60 | * @return array 61 | */ 62 | abstract protected function expectedFilters(); 63 | } 64 | -------------------------------------------------------------------------------- /tests/tests/Extension/JTextTest.php: -------------------------------------------------------------------------------- 1 | extension = new JText; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctions() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('jtext', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'jtext' => [ 68 | 'class' => Text::class, 69 | 'method' => '_' 70 | ], 71 | 'jtext_sprintf' => [ 72 | 'class' => Text::class, 73 | 'method' => 'sprintf' 74 | ] 75 | ]; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/tests/Loader/ModuleLoaderTest.php: -------------------------------------------------------------------------------- 1 | getMethod('getTemplatePaths'); 32 | $method->setAccessible(true); 33 | 34 | $expected = [ 35 | JPATH_BASE . '/templates/' . \JFactory::getApplication()->getTemplate() . '/html', 36 | JPATH_BASE . '/modules' 37 | ]; 38 | 39 | $this->assertSame($expected, $method->invoke($loader)); 40 | } 41 | 42 | /** 43 | * parseExtensionName returns expected parts. 44 | * 45 | * @return void 46 | */ 47 | public function testParseExtensionNameReturnsExpectedParts() 48 | { 49 | $loader = new ModuleLoader; 50 | 51 | $reflection = new \ReflectionClass($loader); 52 | $method = $reflection->getMethod('parseExtensionName'); 53 | $method->setAccessible(true); 54 | 55 | $name = '@module/mod_menu/default.html.twig'; 56 | $expected = '@module/mod_menu/tmpl/default.html.twig'; 57 | 58 | $this->assertSame($expected, $method->invoke($loader, $name)); 59 | 60 | $name = '@module'; 61 | $expected = '@module'; 62 | 63 | $this->assertSame($expected, $method->invoke($loader, $name)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Traits/HasParams.php: -------------------------------------------------------------------------------- 1 | params->get($name, $defaultValue); 41 | } 42 | 43 | /** 44 | * Get active parameters. 45 | * 46 | * @return Registry 47 | */ 48 | public function getParams() 49 | { 50 | return $this->params; 51 | } 52 | 53 | /** 54 | * Set the value of a parameter. 55 | * 56 | * @param string $name Name of the parameter to set. 57 | * @param mixed $value Value to assign. 58 | * 59 | * @return self 60 | */ 61 | public function setParam($name, $value) 62 | { 63 | $this->params->set($name, $value); 64 | 65 | return $this; 66 | } 67 | 68 | /** 69 | * Set active parameters. 70 | * 71 | * @param array|Registry $params Parameters to set 72 | * 73 | * @return self 74 | */ 75 | public function setParams($params) 76 | { 77 | $this->params = $params instanceof Registry ? $params : new Registry($params); 78 | 79 | return $this; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tests/tests/Loader/ComponentLoaderTest.php: -------------------------------------------------------------------------------- 1 | getMethod('getTemplatePaths'); 32 | $method->setAccessible(true); 33 | 34 | $expected = [ 35 | JPATH_BASE . '/templates/' . \JFactory::getApplication()->getTemplate() . '/html', 36 | JPATH_BASE . '/components' 37 | ]; 38 | 39 | $this->assertSame($expected, $method->invoke($loader)); 40 | } 41 | 42 | /** 43 | * parseExtensionName returns expected parts. 44 | * 45 | * @return void 46 | */ 47 | public function testParseExtensionNameReturnsExpectedParts() 48 | { 49 | $loader = new ComponentLoader; 50 | 51 | $reflection = new \ReflectionClass($loader); 52 | $method = $reflection->getMethod('parseExtensionName'); 53 | $method->setAccessible(true); 54 | 55 | $name = '@component/com_users/login/default.html.twig'; 56 | $expected = '@component/com_users/views/login/tmpl/default.html.twig'; 57 | 58 | $this->assertSame($expected, $method->invoke($loader, $name)); 59 | 60 | $name = '@component'; 61 | $expected = '@component'; 62 | 63 | $this->assertSame($expected, $method->invoke($loader, $name)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/tests/Extension/JModuleHelperTest.php: -------------------------------------------------------------------------------- 1 | extension = new JModuleHelper; 37 | } 38 | 39 | /** 40 | * Test getFunctions returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFunctions() 45 | { 46 | $this->genericFunctionsTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsCorrectName() 55 | { 56 | $this->assertEquals('jmodule', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * Functions expected to be added by the extension. 61 | * 62 | * @return array 63 | */ 64 | protected function expectedFunctions() 65 | { 66 | return [ 67 | 'jmodule_get_module' => [ 68 | 'class' => ModuleHelper::class, 69 | 'method' => 'getModule' 70 | ], 71 | 'jmodule_get_modules' => [ 72 | 'class' => ModuleHelper::class, 73 | 'method' => 'getModules' 74 | ], 75 | 'jmodule_render_module' => [ 76 | 'class' => ModuleHelper::class, 77 | 'method' => 'renderModule' 78 | ] 79 | ]; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ## Quick start. 2 | 3 | While a full documentation is written here is a quick start. 4 | 5 | To start using twig layout you have to include the library call: 6 | 7 | ```php 8 | JLoader::import('twig.library'); 9 | ``` 10 | 11 | Then you can render any component, module, library, plugin or template layout like: 12 | 13 | ### Component view layout 14 | 15 | ```php 16 | /** 17 | * Render a component view layout. This will search for layouts in: 18 | * - templates/{ACTIVE_TEMPLATE}/html/com_users/login/default.html.twig 19 | * - components/com_users/views/login/default.html.twig 20 | */ 21 | echo Twig::render('@component/com_users/login/default.html.twig'); 22 | ``` 23 | 24 | ### Module layout 25 | 26 | ```php 27 | /** 28 | * Render a module layout. This will search for layouts in: 29 | * - templates/{ACTIVE_TEMPLATE}/html/mod_menu/default.html.twig 30 | * - modules/mod_menu/tmpl/default.html.twig 31 | */ 32 | echo Twig::render('@module/mod_menu/default.html.twig'); 33 | ``` 34 | 35 | ### Library layout 36 | 37 | ```php 38 | /** 39 | * Render a library layout. This will search for layouts in: 40 | * - templates/{ACTIVE_TEMPLATE}/html/libraries/phproberto/default.html.twig 41 | * - libraries/phproberto/layouts/default.html.twig 42 | */ 43 | echo Twig::render('@library/phproberto/default.html.twig'); 44 | ``` 45 | 46 | ### Plugin layout 47 | 48 | ```php 49 | /** 50 | * Render a plugin layout. This will search for layouts in: 51 | * - templates/{ACTIVE_TEMPLATE}/html/plugins/content/joomla/default.html.twig 52 | * - plugins/content/joomla/tmpl/default.html.twig 53 | */ 54 | echo Twig::render('@plugin/content/joomla/default.html.twig'); 55 | ``` 56 | 57 | ### Template layout 58 | 59 | ```php 60 | /** 61 | * Render a template layout. This will search for layouts in: 62 | * - templates/{ACTIVE_TEMPLATE}/html/default.html.twig 63 | */ 64 | echo Twig::render('@template/default.html.twig'); 65 | ``` 66 | -------------------------------------------------------------------------------- /tests/tests/Traits/HasParamsTest.php: -------------------------------------------------------------------------------- 1 | getMockForTrait(HasParams::class); 32 | 33 | $this->assertSame($mock, $mock->setParams([])); 34 | $this->assertSame(null, $mock->getParam('my-key')); 35 | $this->assertSame('default', $mock->getParam('my-key', 'default')); 36 | } 37 | 38 | /** 39 | * @test 40 | * 41 | * @return void 42 | */ 43 | public function setParamsSetsParams() 44 | { 45 | $mock = $this->getMockForTrait(HasParams::class); 46 | 47 | $params = ['test' => 'value', 'other' => 'diff-value']; 48 | 49 | $this->assertSame($mock, $mock->setParams($params)); 50 | 51 | $registry = $mock->getParams(); 52 | $this->assertInstanceOf(Registry::class, $registry); 53 | 54 | foreach ($params as $key => $value) 55 | { 56 | $this->assertSame($value, $registry->get($key)); 57 | } 58 | } 59 | 60 | /** 61 | * @test 62 | * 63 | * @return void 64 | */ 65 | public function setParamSetsParam() 66 | { 67 | $mock = $this->getMockForTrait(HasParams::class); 68 | 69 | $this->assertSame($mock, $mock->setParams([])); 70 | 71 | $this->assertSame($mock, $mock->setParam('my-key', 'my-value')); 72 | $this->assertSame('my-value', $mock->getParam('my-key')); 73 | 74 | $this->assertSame($mock, $mock->setParam('my-key', null)); 75 | $this->assertSame(null, $mock->getParam('my-key')); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /docs/_data/sidebar.yml: -------------------------------------------------------------------------------- 1 | - title: Basics 2 | links: 3 | - title: Quick start 4 | url: / 5 | - title: Contributing 6 | url: /contributing 7 | - title: License 8 | url: /license 9 | - title: Usage 10 | links: 11 | - title: Modules 12 | url: /usage/modules 13 | - title: Views 14 | url: /usage/views 15 | - title: Global variables 16 | links: 17 | - title: japp 18 | url: /globals/japp 19 | - title: jdoc 20 | url: /globals/jdoc 21 | - title: jlang 22 | url: /globals/jlang 23 | - title: jsession 24 | url: /globals/jsession 25 | - title: juri 26 | url: /globals/juri 27 | - title: juser 28 | url: /globals/juser 29 | - title: Functions 30 | links: 31 | - title: jhtml() 32 | url: /functions/jhtml 33 | - title: jlang() 34 | url: /functions/jlang 35 | - title: jlayout() 36 | url: /functions/jlayout 37 | - title: jlayout_debug() 38 | url: /functions/jlayout_debug 39 | - title: jlayout_render() 40 | url: /functions/jlayout_render 41 | - title: jmodule_get_module() 42 | url: /functions/jmodule_get_module 43 | - title: jmodule_get_modules() 44 | url: /functions/jmodule_get_modules 45 | - title: jmodule_render_module() 46 | url: /functions/jmodule_render_module 47 | - title: jposition() 48 | url: /functions/jposition 49 | - title: jprofiler() 50 | url: /functions/jprofiler 51 | - title: jregistry() 52 | url: /functions/jregistry 53 | - title: jroute() 54 | url: /functions/jroute 55 | - title: jtext() 56 | url: /functions/jtext 57 | - title: jtext_sprintf() 58 | url: /functions/jtext_sprintf 59 | - title: juri() 60 | url: /functions/juri 61 | - title: juser() 62 | url: /functions/juser 63 | - title: Filters 64 | links: 65 | - title: to_array 66 | url: /filters/to_array 67 | - title: unserialize 68 | url: /filters/unserialize 69 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Extension/JPosition.php: -------------------------------------------------------------------------------- 1 | ['html']]) 36 | ]; 37 | } 38 | 39 | /** 40 | * Render the module position. 41 | * 42 | * @param string $position Position to render 43 | * @param array $attribs Associative array of values 44 | * 45 | * @return string 46 | */ 47 | public function render(string $position, array $attribs = []) : string 48 | { 49 | $modules = ModuleHelper::getModules($position); 50 | $renderer = $this->getModuleRenderer(); 51 | $html = ''; 52 | 53 | foreach ($modules as $module) 54 | { 55 | $html .= $renderer->render($module, $attribs); 56 | } 57 | 58 | return $html; 59 | } 60 | 61 | /** 62 | * Get an instance of the module renderer. 63 | * 64 | * @return ModuleRenderer 65 | * 66 | * @codeCoverageIgnore 67 | */ 68 | protected function getModuleRenderer() : ModuleRenderer 69 | { 70 | return Factory::getDocument()->loadRenderer('module'); 71 | } 72 | 73 | /** 74 | * Get the name of this extension. 75 | * 76 | * @return string 77 | */ 78 | public function getName() : string 79 | { 80 | return 'jposition'; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tests/tests/Extension/JArrayTest.php: -------------------------------------------------------------------------------- 1 | extension = new JArray; 37 | } 38 | 39 | /** 40 | * Test getFilters returns correct data. 41 | * 42 | * @return void 43 | */ 44 | public function testGetFiltersReturnsCorrectData() 45 | { 46 | $this->genericFiltersTest(); 47 | } 48 | 49 | /** 50 | * getName returns correct extension name. 51 | * 52 | * @return void 53 | */ 54 | public function testGetNameReturnsJapp() 55 | { 56 | $this->assertEquals('jarray', $this->extension->getName()); 57 | } 58 | 59 | /** 60 | * toArray casts data. 61 | * 62 | * @return void 63 | */ 64 | public function testToArrayCastsData() 65 | { 66 | $this->assertSame([2], $this->extension->toArray(2)); 67 | $this->assertSame(['test'], $this->extension->toArray('test')); 68 | } 69 | 70 | /** 71 | * Functions expected to be added by the extension. 72 | * 73 | * @return array 74 | */ 75 | protected function expectedFilters() 76 | { 77 | return [ 78 | 'to_array' => [ 79 | 'class' => JArray::class, 80 | 'method' => 'toArray' 81 | ], 82 | 'array_values' => [ 83 | 'class' => null, 84 | 'method' => 'array_values' 85 | ] 86 | ]; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tests/tests/Loader/LibraryLoaderTest.php: -------------------------------------------------------------------------------- 1 | getMethod('getTemplatePaths'); 32 | $method->setAccessible(true); 33 | 34 | $expected = [ 35 | JPATH_BASE . '/templates/' . \JFactory::getApplication()->getTemplate() . '/html/libraries', 36 | JPATH_LIBRARIES 37 | ]; 38 | 39 | // Try to create any missing folder 40 | foreach ($expected as $folder) 41 | { 42 | if (!is_dir($folder) && !mkdir($folder)) 43 | { 44 | throw new \Exception("Error creating folder " . $folder); 45 | } 46 | } 47 | 48 | $this->assertSame($expected, $method->invoke($loader)); 49 | } 50 | 51 | /** 52 | * parseExtensionName returns expected parts. 53 | * 54 | * @return void 55 | */ 56 | public function testParseExtensionNameReturnsExpectedParts() 57 | { 58 | $loader = new LibraryLoader; 59 | 60 | $reflection = new \ReflectionClass($loader); 61 | $method = $reflection->getMethod('parseExtensionName'); 62 | $method->setAccessible(true); 63 | 64 | $name = '@library/joomla/default.html.twig'; 65 | $expected = '@library/joomla/layouts/default.html.twig'; 66 | 67 | $this->assertSame($expected, $method->invoke($loader, $name)); 68 | 69 | $name = '@library'; 70 | $expected = '@library'; 71 | 72 | $this->assertSame($expected, $method->invoke($loader, $name)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/tests/Extension/JLanguageTest.php: -------------------------------------------------------------------------------- 1 | saveFactoryState(); 37 | \JFactory::$session = $this->getMockSession(); 38 | \JFactory::$config = $this->getMockConfig(); 39 | \JFactory::$application = $this->getMockCmsApp(); 40 | 41 | $this->extension = new JLanguage; 42 | } 43 | 44 | /** 45 | * Tears down the fixture, for example, closes a network connection. 46 | * This method is called after a test is executed. 47 | * 48 | * @return void 49 | */ 50 | protected function tearDown() 51 | { 52 | $this->restoreFactoryState(); 53 | parent::tearDown(); 54 | } 55 | 56 | /** 57 | * Test getFunctions returns correct data. 58 | * 59 | * @return void 60 | */ 61 | public function testGetFunctions() 62 | { 63 | $this->genericFunctionsTest(); 64 | } 65 | 66 | /** 67 | * getName returns correct name. 68 | * 69 | * @return void 70 | */ 71 | public function testGetNameReturnsCorrectName() 72 | { 73 | $this->assertEquals('jlang', $this->extension->getName()); 74 | } 75 | 76 | /** 77 | * Functions expected to be added by the extension. 78 | * 79 | * @return array 80 | */ 81 | protected function expectedFunctions() 82 | { 83 | return [ 84 | 'jlang' => [ 85 | 'class' => Language::class, 86 | 'method' => 'getInstance' 87 | ] 88 | ]; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Twig.php: -------------------------------------------------------------------------------- 1 | environment = new Environment($loader); 52 | } 53 | 54 | /** 55 | * Clear the cached instance. 56 | * 57 | * @return void 58 | */ 59 | public static function clear() 60 | { 61 | self::$instance = null; 62 | } 63 | 64 | /** 65 | * Get the cached instance 66 | * 67 | * @return static 68 | */ 69 | public static function instance() : Twig 70 | { 71 | if (null === self::$instance) 72 | { 73 | self::$instance = new self; 74 | } 75 | 76 | return self::$instance; 77 | } 78 | 79 | /** 80 | * Render a layout. 81 | * 82 | * @param string $layout Template to render 83 | * @param array $data Optional data for the layout 84 | * 85 | * @return string 86 | */ 87 | public static function render(string $layout, array $data = []) : string 88 | { 89 | return self::instance()->environment()->render($layout, $data); 90 | } 91 | 92 | /** 93 | * Retrieve the environment. 94 | * 95 | * @return self 96 | */ 97 | public function environment() : Environment 98 | { 99 | return $this->environment; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /tests/tests/Loader/BaseExtensionLoaderTest.php: -------------------------------------------------------------------------------- 1 | saveFactoryState(); 32 | 33 | $_SERVER['HTTP_HOST'] = 'mydomain.com'; 34 | $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0'; 35 | $_SERVER['REQUEST_URI'] = '/index.php'; 36 | $_SERVER['SCRIPT_NAME'] = '/index.php'; 37 | 38 | \JFactory::$config = $this->getMockConfig(); 39 | \JFactory::$document = $this->getMockDocument(); 40 | \JFactory::$language = $this->getMockLanguage(); 41 | \JFactory::$session = $this->getMockSession(); 42 | \JFactory::$application = new SiteApplication($this->getMockInput(), new Registry(['session' => false])); 43 | } 44 | 45 | /** 46 | * Tears down the fixture, for example, closes a network connection. 47 | * This method is called after a test is executed. 48 | * 49 | * @return void 50 | */ 51 | protected function tearDown() 52 | { 53 | $this->restoreFactoryState(); 54 | parent::tearDown(); 55 | } 56 | 57 | /** 58 | * Gets the data set to be loaded into the database during setup 59 | * 60 | * @return \PHPUnit_Extensions_Database_DataSet_CsvDataSet 61 | */ 62 | protected function getDataSet() 63 | { 64 | $dataSet = new \PHPUnit_Extensions_Database_DataSet_CsvDataSet(',', "'", '\\'); 65 | $dataSet->addTable('jos_extensions', JPATH_TEST_DATABASE . '/jos_extensions.csv'); 66 | $dataSet->addTable('jos_template_styles', JPATH_TEST_DATABASE . '/jos_template_styles.csv'); 67 | 68 | return $dataSet; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /extensions/plugins/twig/cache/cache.php: -------------------------------------------------------------------------------- 1 | isEnabled()) 62 | { 63 | return; 64 | } 65 | 66 | $cacheFolder = Factory::getConfig()->get('cache_path', JPATH_CACHE) . '/twig'; 67 | 68 | if ($cacheFolder !== JPATH_CACHE) 69 | { 70 | $cacheFolder .= '/' . (Factory::getApplication()->isSite() ? 'site' : 'admin'); 71 | } 72 | 73 | $options['cache'] = $cacheFolder; 74 | } 75 | 76 | /** 77 | * Check if the cache is enabled. 78 | * 79 | * @return boolean 80 | * 81 | * @since 1.1.0 82 | */ 83 | private function isEnabled() 84 | { 85 | $status = (int) $this->params->get('enabled', 0); 86 | 87 | if (self::STATUS_INHERITED === $status) 88 | { 89 | return (0 !== (int) Factory::getConfig()->get('caching')); 90 | } 91 | 92 | return $status === self::STATUS_ENABLED; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/tests/Extension/JRegistryTest.php: -------------------------------------------------------------------------------- 1 | extension = new JRegistry; 39 | } 40 | 41 | /** 42 | * Test getFunctions returns correct data. 43 | * 44 | * @return void 45 | */ 46 | public function testGetFunctions() 47 | { 48 | $this->genericFunctionsTest(); 49 | } 50 | 51 | /** 52 | * getName returns correct name. 53 | * 54 | * @return void 55 | */ 56 | public function testGetNameReturnsCorrectName() 57 | { 58 | $this->assertEquals('jregistry', $this->extension->getName()); 59 | } 60 | 61 | /** 62 | * @test 63 | * 64 | * @return void 65 | */ 66 | public function getRegistryReturnsExpectedValue() 67 | { 68 | $this->assertInstanceOf(Registry::class, $this->extension->getRegistry()); 69 | 70 | $registryFromString = $this->extension->getRegistry('{"property":"a-value"}'); 71 | 72 | $this->assertSame("a-value", $registryFromString->get('property')); 73 | 74 | $registryFromArray = $this->extension->getRegistry(['name' => 'Roberto']); 75 | 76 | $this->assertSame("Roberto", $registryFromArray->get('name')); 77 | $this->assertSame("Segura", $registryFromArray->get('last_name', 'Segura')); 78 | } 79 | 80 | /** 81 | * Functions expected to be added by the extension. 82 | * 83 | * @return array 84 | */ 85 | protected function expectedFunctions() 86 | { 87 | return [ 88 | 'jregistry' => [ 89 | 'class' => JRegistry::class, 90 | 'method' => 'getRegistry' 91 | ] 92 | ]; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /extensions/libraries/twig/layouts/examples.html.twig: -------------------------------------------------------------------------------- 1 |

Twig examples:

2 |
3 | 4 |

japp.getClientId()

5 | {{ dump(japp.getClientId()) }} 6 |
7 | 8 |

34|to_array

9 | {{ dump(34|to_array) }} 10 |
11 | 12 |

jdoc.template

13 | {{ dump(jdoc.template) }} 14 |
15 | 16 |

jhtml('form.token')

17 | {{ dump(jhtml('form.token')) }} 18 |
19 | 20 |

jlang.getName()

21 | {{ dump(jlang.getName()) }} 22 |
23 | 24 |

jlang('es-ES').getName():

25 | {{ dump(jlang('es-ES').getName()) }} 26 |
27 | 28 |

jlayout('joomla.html.treeprefix', constant('JPATH_SITE') ~ '/media', {'debug' : true}):

29 |
30 | {% set options = {'debug' : true} %} 31 | {% set layout = jlayout('joomla.html.treeprefix', constant('JPATH_SITE') ~ '/media', options) %} 32 | 33 |

LayoutId:

34 | {{ dump(layout.getLayoutId()) }} 35 |
36 | 37 |

IncludePaths:

38 | {{ dump(layout.getIncludePaths()) }} 39 |
40 | 41 |

Render:

42 | {{ dump(layout.render({'level' : 10})) }} 43 |
44 | 45 |

jposition('position-8')

46 | {{ dump(jposition('position-8')) }} 47 |
48 | 49 |

jprofiler('joomla-twig')

50 |
51 | {% set profiler = jprofiler('joomla-twig') %} 52 |

mark:

53 | {{ dump(profiler.mark('before something')) }} 54 |

mark 2:

55 | {{ dump(profiler.mark('after something')) }} 56 |
57 |
58 | 59 |

jroute('index.php?option=com_content&view=category&id=27')

60 | {{ dump(jroute('index.php?option=com_content&view=category&id=27')) }} 61 |
62 | 63 |

jsession.getToken()

64 | {{ dump(jsession.getToken()) }} 65 |
66 | 67 |

jtext('JENABLED')

68 | {{ dump(jtext('JENABLED')) }} 69 |
70 | 71 |

jtext_sprintf('JNEXT_TITLE', 'My article title')

72 | {{ dump(jtext_sprintf('JNEXT_TITLE', 'My article title')) }} 73 |
74 | 75 |

juri

76 | {{ dump(juri) }} 77 |
78 | 79 |

juri('index.php?option=com_content&view=category')

80 | {{ dump(juri('index.php?option=com_content&view=category')) }} 81 |
82 | 83 |

juser.get('guest')

84 | {{ dump(juser.get('guest')) }} 85 |
86 | 87 |

juser(668).email

88 | {{ dump(juser(668).email) }} 89 |
90 | 91 |

's:6:"foobar";'|unserialize

92 | {{ dump('s:6:"foobar";'|unserialize) }} 93 |
94 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Field/ModuleLayout.php: -------------------------------------------------------------------------------- 1 | module); 45 | } 46 | 47 | /** 48 | * Get the folders that we will scan for layouts. 49 | * 50 | * @return array 51 | */ 52 | public function layoutFolders() : array 53 | { 54 | $appFolder = $this->clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; 55 | 56 | return [ 57 | Text::_('LIB_TWIG_LBL_MODULE') => $appFolder . '/modules/' . $this->module . '/tmpl', 58 | Text::_('LIB_TWIG_LBL_TEMPLATE') => $appFolder . '/templates/' . $this->activeTemplate() . '/html/' . $this->module 59 | ]; 60 | } 61 | 62 | /** 63 | * Method to attach a JForm object to the field. 64 | * 65 | * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. 66 | * @param mixed $value The form field value to validate. 67 | * @param string $group The field name group control value. This acts as as an array container for the field. 68 | * For example if the field has name="foo" and the group value is set to "bar" then the 69 | * full field name would end up being "bar[foo]". 70 | * 71 | * @return boolean True on success. 72 | * 73 | * @see JFormField::setup() 74 | */ 75 | public function setup(\SimpleXMLElement $element, $value, $group = null) 76 | { 77 | if (!parent::setup($element, $value, $group)) 78 | { 79 | return false; 80 | } 81 | 82 | $this->__set('module', $this->getAttribute('module')); 83 | 84 | return true; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/View/Traits/HasTwigRenderer.php: -------------------------------------------------------------------------------- 1 | option) 45 | { 46 | $this->option = $this->getOptionFromPrefix(); 47 | } 48 | 49 | return $this->option; 50 | } 51 | 52 | /** 53 | * Get the component from the prefix. Ex.: ContentViewArticle will return com_content 54 | * 55 | * @return string 56 | */ 57 | protected function getOptionFromPrefix() 58 | { 59 | $class = get_class($this); 60 | 61 | if (false !== strpos($class, '\\')) 62 | { 63 | $name = array_filter(explode('\\', strstr($class, 'View', true))); 64 | $name = strtolower(end($name)); 65 | } 66 | else 67 | { 68 | $name = strtolower(strstr($class, 'View', true)); 69 | } 70 | 71 | return 'com_' . strtolower($name); 72 | } 73 | 74 | /** 75 | * Load a template file -- first look in the templates folder for an override 76 | * 77 | * @param string $tpl The name of the template source file; automatically searches the template paths and compiles as needed. 78 | * 79 | * @return string The output of the the template script. 80 | * 81 | * @throws \Exception 82 | */ 83 | public function loadTemplate($tpl = null) 84 | { 85 | $layout = $this->getLayout(); 86 | $tpl = $tpl ? $layout . '_' . $tpl : $layout; 87 | 88 | $renderer = Twig::instance(); 89 | 90 | $data = $this->getLayoutData(); 91 | $prefix = '@component/' . $this->getOption() . '/' . $this->getName(); 92 | 93 | $name = $prefix . '/' . $tpl . '.html.twig'; 94 | 95 | if ($renderer->environment()->getLoader()->exists($name)) 96 | { 97 | return $renderer->render($name, $data); 98 | } 99 | 100 | $name = $prefix . '/default.html.twig'; 101 | 102 | return $renderer->render($name, $data); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Module/BaseTwigModule.php: -------------------------------------------------------------------------------- 1 | setParams($params); 49 | $this->module = $module ? $module : new \stdClass; 50 | } 51 | 52 | /** 53 | * CSS class assignable to the module. 54 | * 55 | * @return string 56 | */ 57 | protected function getCssClass() : string 58 | { 59 | return str_replace('_', '-', $this->getElement()); 60 | } 61 | 62 | /** 63 | * Create an unique CSS identifier for the module. 64 | * 65 | * @return string 66 | */ 67 | protected function getCssId() : string 68 | { 69 | return $this->getCssClass() . '-' . $this->getId(); 70 | } 71 | 72 | /** 73 | * Get module element. 74 | * 75 | * @return string 76 | */ 77 | public function getElement() : string 78 | { 79 | if (null === $this->element) 80 | { 81 | $this->element = empty($this->module->module) ? basename(dirname(__DIR__)) : $this->module->module; 82 | } 83 | 84 | return $this->element; 85 | } 86 | 87 | /** 88 | * Get the module identifier. 89 | * 90 | * @return string 91 | */ 92 | public function getId() : string 93 | { 94 | return empty($this->module->id) ? uniqid() : $this->module->id; 95 | } 96 | 97 | /** 98 | * Load layout data. 99 | * 100 | * @return array 101 | */ 102 | protected function loadLayoutData() : array 103 | { 104 | return [ 105 | 'cssClass' => $this->getCssClass(), 106 | 'cssId' => $this->getCssId(), 107 | 'moduleInstance' => $this, 108 | 'params' => $this->getParams() 109 | ]; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /tests/tests/Extension/JLayoutTest.php: -------------------------------------------------------------------------------- 1 | saveFactoryState(); 37 | \JFactory::$application = $this->getMockCmsApp(); 38 | 39 | $this->extension = new JLayout; 40 | } 41 | 42 | /** 43 | * Tears down the fixture, for example, closes a network connection. 44 | * This method is called after a test is executed. 45 | * 46 | * @return void 47 | */ 48 | protected function tearDown() 49 | { 50 | $this->restoreFactoryState(); 51 | parent::tearDown(); 52 | } 53 | 54 | /** 55 | * Test getFunctions returns correct data. 56 | * 57 | * @return void 58 | */ 59 | public function testGetFunctions() 60 | { 61 | $this->genericFunctionsTest(); 62 | } 63 | 64 | /** 65 | * getName returns correct name. 66 | * 67 | * @return void 68 | */ 69 | public function testGetNameReturnsCorrectName() 70 | { 71 | $this->assertEquals('jlayout', $this->extension->getName()); 72 | } 73 | 74 | /** 75 | * jlayout returns a FileLayout instance. 76 | * 77 | * @return void 78 | */ 79 | public function testJlayoutReturnsAFileLayoutInstance() 80 | { 81 | $fileLayout = $this->extension->getFileLayout('joomla.system.message'); 82 | 83 | $this->assertInstanceOf(FileLayout::class, $fileLayout); 84 | $this->assertSame('joomla.system.message', $fileLayout->getLayoutId()); 85 | } 86 | 87 | /** 88 | * Functions expected to be added by the extension. 89 | * 90 | * @return array 91 | */ 92 | protected function expectedFunctions() 93 | { 94 | return [ 95 | 'jlayout' => [ 96 | 'class' => JLayout::class, 97 | 'method' => 'getFileLayout' 98 | ], 99 | 'jlayout_render' => [ 100 | 'class' => LayoutHelper::class, 101 | 'method' => 'render' 102 | ], 103 | 'jlayout_debug' => [ 104 | 'class' => LayoutHelper::class, 105 | 'method' => 'debug' 106 | ] 107 | ]; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Field/ViewLayout.php: -------------------------------------------------------------------------------- 1 | component . '|' . $this->view); 52 | } 53 | 54 | /** 55 | * Get the folders that we will scan for layouts. 56 | * 57 | * @return array 58 | */ 59 | public function layoutFolders() : array 60 | { 61 | $appFolder = $this->clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; 62 | 63 | $mainFolder = $appFolder . '/components/' . $this->component . '/views/' . $this->view . '/tmpl'; 64 | $overridesFolder = $appFolder . '/templates/' . $this->activeTemplate() . '/html/' . $this->component . '/' . $this->view; 65 | 66 | return [ 67 | Text::_('LIB_TWIG_LBL_COMPONENT') => $mainFolder, 68 | Text::_('LIB_TWIG_LBL_TEMPLATE') => $overridesFolder 69 | ]; 70 | } 71 | 72 | /** 73 | * Method to attach a JForm object to the field. 74 | * 75 | * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. 76 | * @param mixed $value The form field value to validate. 77 | * @param string $group The field name group control value. This acts as as an array container for the field. 78 | * For example if the field has name="foo" and the group value is set to "bar" then the 79 | * full field name would end up being "bar[foo]". 80 | * 81 | * @return boolean True on success. 82 | * 83 | * @see JFormField::setup() 84 | */ 85 | public function setup(\SimpleXMLElement $element, $value, $group = null) 86 | { 87 | if (!parent::setup($element, $value, $group)) 88 | { 89 | return false; 90 | } 91 | 92 | $this->__set('component', $this->getAttribute('component')); 93 | $this->__set('view', $this->getAttribute('view')); 94 | 95 | return true; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /extensions/plugins/twig/debug/debug.php: -------------------------------------------------------------------------------- 1 | isDebugEnabled(); 66 | } 67 | 68 | /** 69 | * Triggered after environment has been loaded. 70 | * 71 | * @param Environment $environment Loaded environment 72 | * @param array $options Options to initialise environment 73 | * 74 | * @return void 75 | */ 76 | public function onTwigAfterLoad(Environment $environment, $options = []) 77 | { 78 | if ($this->isDebugEnabled()) 79 | { 80 | $environment->addExtension(new DebugExtension); 81 | } 82 | } 83 | 84 | /** 85 | * Check if debug is enabled. 86 | * 87 | * @return boolean 88 | */ 89 | private function isDebugEnabled() 90 | { 91 | if (null === $this->isDebugEnabled) 92 | { 93 | $this->isDebugEnabled = $this->checkDebugEnabled(); 94 | } 95 | 96 | return $this->isDebugEnabled; 97 | } 98 | 99 | /** 100 | * Check the debug status. 101 | * 102 | * @return boolean 103 | */ 104 | private function checkDebugEnabled() 105 | { 106 | $mode = $this->params->get('mode', self::DEBUG_AUTO); 107 | 108 | if ($mode === self::DEBUG_AUTO) 109 | { 110 | return JDEBUG === '1'; 111 | } 112 | 113 | return $mode === self::DEBUG_ALWAYS; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /extensions/pkg_twig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PKG_TWIG 4 | September 2018 5 | Roberto Segura 6 | roberto@phproberto.com 7 | www.phproberto.com 8 | Copyright (C) 2017-2018 Roberto Segura López. All rights reserved. 9 | GNU General Public License version 2 or later, see LICENSE. 10 | Roberto Segura 11 | twig 12 | http://www.phproberto.com 13 | 1.5.0 14 | PKG_TWIG_XML_DESCRIPTION 15 | install.php 16 | 17 | 18 | en-GB/en-GB.pkg_twig.sys.ini 19 | 20 | 21 | 22 | libraries/twig 23 | 24 | 25 | plugins/twig/cache 26 | plugins/twig/debug 27 | plugins/twig/jarray 28 | plugins/twig/japp 29 | plugins/twig/jdoc 30 | plugins/twig/jhtml 31 | plugins/twig/jlang 32 | plugins/twig/jlayout 33 | plugins/twig/jmodule 34 | plugins/twig/jprofiler 35 | plugins/twig/jposition 36 | plugins/twig/jregistry 37 | plugins/twig/jroute 38 | plugins/twig/jsession 39 | plugins/twig/jtext 40 | plugins/twig/juri 41 | plugins/twig/juser 42 | plugins/twig/unserialize 43 | 44 | 45 | https://raw.githubusercontent.com/phproberto/joomla-twig/master/updates/twig_update.xml 46 | 47 | 48 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Field/PluginLayout.php: -------------------------------------------------------------------------------- 1 | pluginGroup . '|' . $this->pluginName); 52 | } 53 | 54 | /** 55 | * Get the folders that we will scan for layouts. 56 | * 57 | * @return array 58 | */ 59 | public function layoutFolders() : array 60 | { 61 | $appFolder = $this->clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; 62 | 63 | $mainFolder = $appFolder . '/plugins/' . $this->pluginGroup . '/' . $this->pluginName . '/tmpl'; 64 | $overridesFolder = $appFolder . '/templates/' . $this->activeTemplate() . '/html/plugins/' . $this->pluginGroup . '/' . $this->pluginName; 65 | 66 | return [ 67 | Text::_('LIB_TWIG_LBL_PLUGIN') => $mainFolder, 68 | Text::_('LIB_TWIG_LBL_TEMPLATE') => $overridesFolder 69 | ]; 70 | } 71 | 72 | /** 73 | * Method to attach a JForm object to the field. 74 | * 75 | * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. 76 | * @param mixed $value The form field value to validate. 77 | * @param string $group The field name group control value. This acts as as an array container for the field. 78 | * For example if the field has name="foo" and the group value is set to "bar" then the 79 | * full field name would end up being "bar[foo]". 80 | * 81 | * @return boolean True on success. 82 | * 83 | * @see JFormField::setup() 84 | */ 85 | public function setup(\SimpleXMLElement $element, $value, $group = null) 86 | { 87 | if (!parent::setup($element, $value, $group)) 88 | { 89 | return false; 90 | } 91 | 92 | $this->__set('pluginGroup', $this->getAttribute('pluginGroup')); 93 | $this->__set('pluginName', $this->getAttribute('pluginName')); 94 | 95 | return true; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Twig integration for Joomla! 2 | 3 | [![Build Status](https://travis-ci.org/phproberto/joomla-twig.svg?branch=master)](https://travis-ci.org/phproberto/joomla-twig) 4 | 5 | > [Twig 2.0](https://twig.symfony.com/doc/2.x/) & [Twig extensions](http://twig-extensions.readthedocs.io/en/latest/) integration for Joomla! 6 | 7 | ## Index 8 | 9 | * [Description](#description) 10 | * [Installation](#installation) 11 | * [Documentation](#documentation) 12 | * [Requirements](#requirements) 13 | * [Copyright & License](#license) 14 | 15 | ## Description 16 | 17 | After integrating Twig with some projects I found the need to create some kind of standard package that can be used & extended by anbody at any project. 18 | 19 | This Twig integration includes common global variables & functions required when using Twig in Joomla! 20 | 21 | Some highlights: 22 | 23 | * Integrates [Twig 2.0](https://github.com/twigphp/Twig) 24 | * Integrates official [Twig extensions](http://twig-extensions.readthedocs.io/en/latest/) 25 | * Global variables to access active application, active document, session, active user, etc. 26 | * Functions to use JLayout, JProfiler, JRoute, JUri, JLanguage, JHtml, etc. 27 | * Integrated cache. 28 | * Integrated debug mode. 29 | * All the extensions are integrated through plugins so you can extend/replace any plugin you need. 30 | * 100% covered by unit tests. 31 | * SonarCloud is used for QA. Check the [project in SonarCloud](https://sonarcloud.io/dashboard?id=phproberto%3Ajoomla-twig). 32 | 33 | Example usage: 34 | 35 | ```php 36 | JLoader::import('twig.library'); 37 | 38 | // This will render a twig layout in: templates/{ACTIVE_TEMPLATE}/html/view.html.twig 39 | echo Twig::render('@template/view.html.twig'); 40 | ``` 41 | 42 | You can find more examples/usages in the [documentation](https://phproberto.github.io/joomla-twig/); 43 | 44 | ## Installation 45 | 46 | * Ensure that your site meets the requirements 47 | * Download latest version from the [releases section](./releases) 48 | * Install zip file in your site through Extension Manager 49 | 50 | For a fast test you can now use the integrated examples.html.twig inside the library. Enable debug mode in your Joomla configuration and add this code to wherever you want to display examples (for example in your template index.php): 51 | 52 | ```php 53 | JLoader::import('twig.library'); 54 | 55 | echo Twig::render('@library/twig/examples.html.twig'); 56 | ``` 57 | 58 | ## Documentation 59 | 60 | See [https://phproberto.github.io/joomla-twig/](https://phproberto.github.io/joomla-twig/) for detailed documentation. 61 | 62 | ## Requirements 63 | 64 | * PHP 7.0+ or higher 65 | * Joomla! 3.8.1 or higher 66 | 67 | ## Copyright & License 68 | 69 | This library is licensed under [GNU LESSER GENERAL PUBLIC LICENSE](./LICENSE). 70 | 71 | Copyright (C) 2017 [Roberto Segura López](http://phproberto.com) - All rights reserved. 72 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Environment.php: -------------------------------------------------------------------------------- 1 | app = $app ?: $this->activeApplication(); 59 | 60 | $this->trigger('onTwigBeforeLoad', [&$loader, &$options]); 61 | 62 | parent::__construct($loader, $options); 63 | 64 | $this->trigger('onTwigAfterLoad', [$options]); 65 | } 66 | 67 | /** 68 | * Get the active Joomla application. 69 | * 70 | * @return CMSApplication 71 | * 72 | * @since 1.0.2 73 | */ 74 | private function activeApplication() : CMSApplication 75 | { 76 | return Factory::getApplication(); 77 | } 78 | 79 | /** 80 | * Import available plugins. 81 | * 82 | * @return void 83 | */ 84 | private function importPlugins() 85 | { 86 | $importablePluginTypes = array_diff($this->importablePluginTypes, $this->importedPluginTypes); 87 | 88 | foreach ($importablePluginTypes as $pluginType) 89 | { 90 | PluginHelper::importPlugin($pluginType); 91 | 92 | $this->importedPluginTypes[] = $pluginType; 93 | } 94 | } 95 | 96 | /** 97 | * Trigger an event on the attached twig instance. 98 | * 99 | * @param string $event Event to trigger 100 | * @param array $params Params for the event triggered 101 | * 102 | * @return array 103 | */ 104 | public function trigger(string $event, array $params = []) : array 105 | { 106 | $this->importPlugins(); 107 | 108 | // Always send environment as first param 109 | array_unshift($params, $this); 110 | 111 | return (array) $this->app->triggerEvent($event, $params); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /tests/tests/Extension/JPositionTest.php: -------------------------------------------------------------------------------- 1 | saveFactoryState(); 36 | \JFactory::$session = $this->getMockSession(); 37 | \JFactory::$config = $this->getMockConfig(); 38 | \JFactory::$application = $this->getMockCmsApp(); 39 | 40 | $this->extension = new JPosition; 41 | } 42 | 43 | /** 44 | * Tears down the fixture, for example, closes a network connection. 45 | * This method is called after a test is executed. 46 | * 47 | * @return void 48 | */ 49 | protected function tearDown() 50 | { 51 | $this->restoreFactoryState(); 52 | parent::tearDown(); 53 | } 54 | 55 | /** 56 | * Gets the data set to be loaded into the database during setup 57 | * 58 | * @return \PHPUnit_Extensions_Database_DataSet_CsvDataSet 59 | */ 60 | protected function getDataSet() 61 | { 62 | $dataSet = new \PHPUnit_Extensions_Database_DataSet_CsvDataSet(',', "'", '\\'); 63 | $dataSet->addTable('jos_extensions', JPATH_TEST_DATABASE . '/jos_extensions.csv'); 64 | $dataSet->addTable('jos_modules', JPATH_TEST_DATABASE . '/jos_modules.csv'); 65 | $dataSet->addTable('jos_modules_menu', JPATH_TEST_DATABASE . '/jos_modules_menu.csv'); 66 | 67 | return $dataSet; 68 | } 69 | 70 | /** 71 | * Test getFunctions returns correct data. 72 | * 73 | * @return void 74 | */ 75 | public function testGetFunctions() 76 | { 77 | $this->genericFunctionsTest(); 78 | } 79 | 80 | /** 81 | * getName returns correct name. 82 | * 83 | * @return void 84 | */ 85 | public function testGetNameReturnsCorrectName() 86 | { 87 | $this->assertEquals('jposition', $this->extension->getName()); 88 | } 89 | 90 | /** 91 | * render returns correct data. 92 | * 93 | * @return void 94 | */ 95 | public function testRenderReturnsCorrectData() 96 | { 97 | $this->assertTrue(strlen(trim($this->extension->render('position-0'))) > 0); 98 | } 99 | 100 | /** 101 | * Functions expected to be added by the extension. 102 | * 103 | * @return array 104 | */ 105 | protected function expectedFunctions() 106 | { 107 | return [ 108 | 'jposition' => [ 109 | 'class' => JPosition::class, 110 | 'method' => 'render' 111 | ] 112 | ]; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /tests/tests/View/Traits/HasTwigRendererTest.php: -------------------------------------------------------------------------------- 1 | getMockForTrait(HasTwigRenderer::class); 35 | 36 | $reflection = new \ReflectionClass($mock); 37 | $optionProperty = $reflection->getProperty('option'); 38 | $optionProperty->setAccessible(true); 39 | 40 | $this->assertNull($optionProperty->getValue($mock)); 41 | 42 | $optionProperty->setValue($mock, 'com_6monthswithoutsmoking'); 43 | 44 | $this->assertSame('com_6monthswithoutsmoking', $mock->getOption()); 45 | } 46 | 47 | /** 48 | * @test 49 | * 50 | * @return void 51 | */ 52 | public function getOptionDefaultsToOptionFromPrefix() 53 | { 54 | $mock = $this->getMockForTrait( 55 | HasTwigRenderer::class, 56 | [], 57 | 'ContentViewRoberto' 58 | ); 59 | 60 | $reflection = new \ReflectionClass($mock); 61 | $optionProperty = $reflection->getProperty('option'); 62 | $optionProperty->setAccessible(true); 63 | 64 | $this->assertNull($optionProperty->getValue($mock)); 65 | 66 | $this->assertSame('com_content', $mock->getOption()); 67 | } 68 | 69 | /** 70 | * @test 71 | * 72 | * @dataProvider getOptionFromProviderMethodProvider 73 | * 74 | * @return void 75 | */ 76 | public function getOptionFromPrefixReturnsCorrectValue($class, $expectedOption) 77 | { 78 | $mock = $this->getMockForTrait( 79 | HasTwigRenderer::class, 80 | [], 81 | $class 82 | ); 83 | 84 | $this->assertSame($expectedOption, $mock->getOption()); 85 | } 86 | 87 | /** 88 | * @test 89 | * 90 | * @return void 91 | */ 92 | public function getOptionFromPrefixReturnsExpecteValueForNamespacedClass() 93 | { 94 | $view = new ClassWithTwigRenderer; 95 | 96 | $reflection = new \ReflectionClass($view); 97 | $method = $reflection->getMethod('getOptionFromPrefix'); 98 | $method->setAccessible(true); 99 | 100 | $this->assertSame('com_tests', $method->invoke($view)); 101 | } 102 | 103 | /** 104 | * Data provider to test getOptionFromProviderMethod 105 | * 106 | * @return array 107 | */ 108 | public function getOptionFromProviderMethodProvider() 109 | { 110 | return [ 111 | ['ContentViewRoberto', 'com_content'], 112 | ['K2ViewRoberto', 'com_k2'], 113 | ['BannerViewBanner', 'com_banner'], 114 | ['TESTINGViewTest', 'com_testing'] 115 | ]; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/tests/Field/BaseLayoutFieldTest.php: -------------------------------------------------------------------------------- 1 | saveFactoryState(); 32 | 33 | $_SERVER['HTTP_HOST'] = 'mydomain.com'; 34 | $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0'; 35 | $_SERVER['REQUEST_URI'] = '/index.php'; 36 | $_SERVER['SCRIPT_NAME'] = '/index.php'; 37 | 38 | \JFactory::$config = $this->getMockConfig(); 39 | \JFactory::$session = $this->getMockSession(); 40 | \JFactory::$application = new SiteApplication($this->getMockInput(), new Registry(['session' => false])); 41 | } 42 | 43 | /** 44 | * Tears down the fixture, for example, closes a network connection. 45 | * This method is called after a test is executed. 46 | * 47 | * @return void 48 | */ 49 | protected function tearDown() 50 | { 51 | $this->restoreFactoryState(); 52 | parent::tearDown(); 53 | } 54 | 55 | /** 56 | * Gets the data set to be loaded into the database during setup 57 | * 58 | * @return \PHPUnit_Extensions_Database_DataSet_CsvDataSet 59 | */ 60 | protected function getDataSet() 61 | { 62 | $dataSet = new \PHPUnit_Extensions_Database_DataSet_CsvDataSet(',', "'", '\\'); 63 | $dataSet->addTable('jos_extensions', JPATH_TEST_DATABASE . '/jos_extensions.csv'); 64 | $dataSet->addTable('jos_template_styles', JPATH_TEST_DATABASE . '/jos_template_styles.csv'); 65 | 66 | return $dataSet; 67 | } 68 | 69 | /** 70 | * Get a sample module \SimpleXMLElement by its key. 71 | * 72 | * @param string $key Key to identify the sample module. 73 | * 74 | * @return \SimpleXMLElement 75 | */ 76 | protected function element($key = 'default') 77 | { 78 | return new \SimpleXMLElement($this->sampleFields()[$key]); 79 | } 80 | 81 | /** 82 | * Retrieve a sample field. 83 | * 84 | * @param string $key Key to identify the sample module. 85 | * @param string $value Value to assign in field setup 86 | * 87 | * @return ModuleLayout 88 | */ 89 | protected function field($key = 'default', $value = 'default') 90 | { 91 | $class = $this->fieldClass(); 92 | $field = new $class; 93 | 94 | $this->assertTrue( 95 | $field->setup($this->element($key), $value) 96 | ); 97 | 98 | return $field; 99 | } 100 | 101 | /** 102 | * Get the class of the field being tested. 103 | * 104 | * @return array 105 | */ 106 | abstract protected function fieldClass(); 107 | 108 | /** 109 | * Get the sample fields XML strings. 110 | * 111 | * @return array 112 | */ 113 | abstract protected function sampleFields(); 114 | } 115 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at roberto@phproberto.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /extensions/libraries/twig/src/Loader/ExtensionLoader.php: -------------------------------------------------------------------------------- 1 | setPaths($this->getTemplatePaths(), $this->extensionNamespace); 38 | 39 | parent::__construct($paths); 40 | } 41 | 42 | /** 43 | * Get the base path for the active application. 44 | * 45 | * @return string 46 | */ 47 | protected function getBaseAppPath() : string 48 | { 49 | if (Factory::getApplication()->isAdmin()) 50 | { 51 | return JPATH_ADMINISTRATOR; 52 | } 53 | 54 | return JPATH_SITE; 55 | } 56 | 57 | /** 58 | * Get the paths to search for templates. 59 | * 60 | * @return array 61 | */ 62 | abstract protected function getTemplatePaths() : array; 63 | 64 | /** 65 | * Find a template. 66 | * 67 | * @param string $name Name of the template to search 68 | * @param bool $throw Whether to throw an exception when an error occurs 69 | * 70 | * @return mixed 71 | * 72 | * @throws \Twig_Error_Loader 73 | */ 74 | protected function findTemplate($name, $throw = true) 75 | { 76 | if (!$this->nameInExtensionNamespace($name)) 77 | { 78 | return false; 79 | } 80 | 81 | try 82 | { 83 | $result = parent::findTemplate($name, true); 84 | } 85 | catch (\Twig_Error_Loader $e) 86 | { 87 | $result = $this->findParsedNameTemplate($name); 88 | } 89 | 90 | if (!$result && $throw) 91 | { 92 | throw new \Twig_Error_Loader($name); 93 | } 94 | 95 | return $result; 96 | } 97 | 98 | /** 99 | * Find a template with name parsed. 100 | * 101 | * @param string $name Name of the template to search 102 | * 103 | * @return mixed 104 | */ 105 | protected function findParsedNameTemplate(string $name) 106 | { 107 | $parsedName = $this->parseExtensionName($name); 108 | 109 | if ($name === $parsedName) 110 | { 111 | return false; 112 | } 113 | 114 | return parent::findTemplate($parsedName, false); 115 | } 116 | 117 | /** 118 | * Check if a layout name is in current namespace. 119 | * 120 | * @param string $name Name of the current layout 121 | * 122 | * @return boolean 123 | */ 124 | protected function nameInExtensionNamespace(string $name) : bool 125 | { 126 | $nameParts = explode('/', $name); 127 | 128 | return isset($nameParts[0]) && $nameParts[0] === '@' . $this->extensionNamespace; 129 | } 130 | 131 | /** 132 | * Parse a received extension name. 133 | * 134 | * @param string $name Name of the template to search 135 | * 136 | * @return string 137 | */ 138 | protected function parseExtensionName(string $name) : string 139 | { 140 | return $name; 141 | } 142 | } 143 | --------------------------------------------------------------------------------