Visitar URL original
Implement contao templating engine. by tristanlins · Pull Request #16 · contao/core-bundle · GitHub
Skip to content

Implement contao templating engine. - #16

Closed
tristanlins wants to merge 4 commits into
contao:feature/symfony2from
tristanlins:feature/templating-engine
Closed

tristanlins wants to merge 4 commits into
contao:feature/symfony2from
tristanlins:feature/templating-engine

Conversation

@tristanlins

Copy link
Copy Markdown
Contributor

The contao template engine allow us to use $container->get('templating')->render('mod_x', ['foo' => 'bar']); which renders the template mod_x.html5.
It's the same as do $template = new FrontendTemplate('mod_x'); return $template->parse(); in the FE mode, or $template = new BackendTemplate('mod_x'); return $template->parse(); in the BE mode.

Comment thread src/Resources/config/services.yml Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unnecessary as your class does not have a constructor and your are using static call anyway?

@aschempp

aschempp commented Nov 1, 2014

Copy link
Copy Markdown
Member

In general, I dislike this idea.

  1. I can't see any advantage of this approach
  2. The new component is still using legacy components for everything.
  3. It is not on our roadmap to replace templating
  4. It's not tested/not really testable
  5. Not sure if the Twig engine would still be usable?

Maybe @tristanlins can explain more where and why this would be useful at all? We currently only support legacy frontend modules, content elements etc, so I don't see a real strategy here.

@discordier

Copy link
Copy Markdown
Contributor

On 2. Yes, because of 3.
On 3. That's why this approach makes the old templating available for new code without having to rewrite the templates.
On 4. Not yet and as you know, legacy classes are a bit hard to test.
On 5. What should prevent it from being used? It is just another engine.

@tristanlins

Copy link
Copy Markdown
Contributor Author

I can't see any advantage of this approach

I don't need any legacy code (the FrontendTemplate or BackendTemplate class) in the new code.

Not sure if the Twig engine would still be usable?

Yes it will. You can define hundreds of engines if you like.

@tristanlins

Copy link
Copy Markdown
Contributor Author

Maybe @tristanlins can explain more where and why this would be useful at all?

I don't want to use the legacy code directly in the new non-legacy code I write now. I wan't to go the correct way. Even if I use the Contao 3 templating scheme, I can use it through the templating service.

Result: No legacy code is required in new code at all. :-)

@leofeyer

leofeyer commented Nov 4, 2014

Copy link
Copy Markdown
Member

I don't want to use the legacy code directly in the new non-legacy code I write now. I wan't to go the correct way. Even if I use the Contao 3 templating scheme, I can use it through the templating service.

Result: No legacy code is required in new code at all. :-)

Pretty good argument, although I also see @aschempp's point.

@leofeyer leofeyer added this to the 4.0.0 milestone Nov 4, 2014
@tristanlins

Copy link
Copy Markdown
Contributor Author

Pretty good argument, although I also see @aschempp's point.

Me too, my current preference is to enable the twig AND contao engine from the beginning.
Then, with $templating->render('fe_page.html.twig') the twig engine is used. With $templating->render('fe_page') the current Contao engine is used.

I think we need to discuss the current behavior, that the engine is detected by the file type, e.g. $templating->render('fe_page.html.php') use the PHP engine. Using a "full qualified name" is the default in Symfony. If we want to keep the old logic, we need to write our own engine anyway.

@leofeyer

leofeyer commented Nov 5, 2014

Copy link
Copy Markdown
Member

Does this mean we would have to reference our templates like this?

$templating->render('fe_page.html5.php');

And if so, would the file have to be named like this, too?

@aschempp

aschempp commented Nov 5, 2014

Copy link
Copy Markdown
Member

We could also use/recommend the twig engine for Symfony code. But that means we would need to think about template overriding "the new way"...

@leofeyer

leofeyer commented Nov 5, 2014

Copy link
Copy Markdown
Member

Doesn't Symfony provide a way to override templates already?

@aschempp

aschempp commented Nov 5, 2014

Copy link
Copy Markdown
Member

Absolutely, but not with a backend interface ;-)

@tristanlins

Copy link
Copy Markdown
Contributor Author

Does this mean we would have to reference our templates like this?

$templating->render('fe_page.html5.php');

If you like to use the PHP engine: yes.
If you like to use the TWIG engine: $templating->render('fe_page.html5.twig');

Doesn't Symfony provide a way to override templates already?

Partially, if someone request fe_page.html5 you cannot replace it with fe_page.xhtml with the existing logic. You can only overwrite the fe_page.html5 itself by putting it into app/Resources/views.
See http://symfony.com/doc/current/book/templating.html#overriding-bundle-templates

We need to write a custom loader, if we want to keep our current logic.

@aschempp

aschempp commented Nov 5, 2014

Copy link
Copy Markdown
Member

We might just drop XHTML templates in Contao 4? Not sure if that would be a BC break (on API), it would simply be an upgrade-problem. But there are already extensions (like Isotope) not supporting XHTML.

@leofeyer

leofeyer commented Nov 5, 2014

Copy link
Copy Markdown
Member

XHTML support has been dropped already (in 4.0.0-alpha1).

@aschempp

aschempp commented Nov 5, 2014

Copy link
Copy Markdown
Member

very well then 💃

@tristanlins

Copy link
Copy Markdown
Contributor Author

If we only want to support twig, we could change every call to $templating->render('mod_foo.html.twig') and provide a template name parser that "parse" mod_foo into mod_foo.html5 for backwards compatibility. But we should discuss this in a mumble call.

@leofeyer

leofeyer commented Nov 5, 2014

Copy link
Copy Markdown
Member

Definitely.

@leofeyer

leofeyer commented Nov 6, 2014

Copy link
Copy Markdown
Member

We have discussed this on Mumble and found the following problems:

  • The template engine does not allow to choose between BackendTemplate and FrontendTemplate.
  • It is not possible to determine the type by the template prefix or the TL_MODE constant.
  • We could merge the two classes BackendTemplate and FrontendTemplate into a single class, however, the "(parse|output)(Backend|Frontend)Template" hooks would no longer work.

We have not found a good solution yet.

@leofeyer leofeyer closed this Mar 18, 2015
@ghost ghost mentioned this pull request Mar 23, 2015
leofeyer pushed a commit that referenced this pull request Aug 4, 2020
Description
-----------

With @Toflar we have discovered by accident that if a URL is double-encoded (for some reason, doesn't matter) the Contao's `RouteProvider` will eventually throw an error trying to query a database.

```
URL original: drachenlochmuseum-v%25c3%25a4ttis.html
URL decoded: drachenlochmuseum-v%c3%a4ttis.html
URL decoded 2nd time: drachenlochmuseum-vättis.html
```

The decoded URL is used in the database query and that fails because the database driver would like to replace wildcards `%c` with parameters that were not provided.

Stack trace:

```
Exception: Too few arguments to build the query string
#27 vendor/contao/core-bundle/src/Resources/contao/library/Contao/Database/Statement.php(304): replaceWildcards
#26 vendor/contao/core-bundle/src/Resources/contao/library/Contao/Database/Statement.php(249): execute
#25 vendor/contao/core-bundle/src/Resources/contao/library/Contao/Model.php(1102): find
#24 vendor/contao/core-bundle/src/Resources/contao/library/Contao/Model.php(973): findBy
#23 vendor/contao/core-bundle/src/Framework/Adapter.php(38): __call
#22 vendor/contao/core-bundle/src/Routing/RouteProvider.php(493): findPages
#21 vendor/contao/core-bundle/src/Routing/RouteProvider.php(88): getRouteCollectionForRequest
#20 vendor/contao/core-bundle/src/Routing/LegacyRouteProvider.php(43): getRouteCollectionForRequest
#19 vendor/symfony-cmf/routing/src/NestedMatcher/NestedMatcher.php(141): matchRequest
#18 vendor/contao/core-bundle/src/Routing/Matcher/LegacyMatcher.php(69): matchRequest
#17 vendor/symfony-cmf/routing/src/DynamicRouter.php(271): matchRequest
#16 vendor/symfony-cmf/routing/src/ChainRouter.php(188): doMatch
#15 vendor/symfony-cmf/routing/src/ChainRouter.php(158): matchRequest
#14 vendor/symfony/http-kernel/EventListener/RouterListener.php(115): onKernelRequest
#13 vendor/symfony/event-dispatcher/EventDispatcher.php(212): doDispatch
#12 vendor/symfony/event-dispatcher/EventDispatcher.php(44): dispatch
#11 vendor/symfony/http-kernel/HttpKernel.php(126): handleRaw
#10 vendor/symfony/http-kernel/HttpKernel.php(67): handle
#9 vendor/symfony/http-kernel/Kernel.php(198): handle
#8 vendor/symfony/http-kernel/HttpCache/SubRequestHandler.php(85): handle
#7 vendor/symfony/http-kernel/HttpCache/HttpCache.php(448): forward
#6 vendor/symfony/framework-bundle/HttpCache/HttpCache.php(57): forward
#5 vendor/symfony/http-kernel/HttpCache/HttpCache.php(420): fetch
#4 vendor/contao/manager-bundle/src/HttpKernel/ContaoCache.php(46): fetch
#3 vendor/symfony/http-kernel/HttpCache/HttpCache.php(317): lookup
#2 vendor/symfony/http-kernel/HttpCache/HttpCache.php(192): handle
#1 vendor/friendsofsymfony/http-cache/src/SymfonyCache/EventDispatchingHttpCache.php(98): handle
#0 web/app.php(58): null
```

Commits
-------

8ae25820 Fix a potential error if the URL has percentage in it
8caaf252 Fix unit tests
509f7624 Correctly encode the page aliases
leofeyer pushed a commit that referenced this pull request May 29, 2024
… #7248)

Description
-----------

If a `tl_article` record still contains `keywords` from previous Contao versions and you reference this article in an `article` content element, the following warning will appear in the back end:

```
ErrorException: Warning: Undefined global variable $TL_KEYWORDS
#24 /vendor/contao/core-bundle/src/Resources/contao/modules/ModuleArticle.php(207): Contao\ModuleArticle::compile
#23 /vendor/contao/core-bundle/src/Resources/contao/modules/Module.php(214): Contao\Module::generate
#22 /vendor/contao/core-bundle/src/Resources/contao/modules/ModuleArticle.php(70): Contao\ModuleArticle::generate
#21 /vendor/contao/core-bundle/src/Resources/contao/library/Contao/Controller.php(550): Contao\Controller::getArticle
#20 /vendor/contao/core-bundle/src/Resources/contao/elements/ContentArticle.php(30): Contao\ContentArticle::generate
#19 /vendor/contao/core-bundle/src/Resources/contao/library/Contao/Controller.php(622): Contao\Controller::getContentElement
#18 /var/cache/prod/contao/dca/tl_content.php(318): tl_content::addCteType
#17 /vendor/contao/core-bundle/src/Resources/contao/drivers/DC_Table.php(4717): Contao\DC_Table::parentView
#16 /vendor/contao/core-bundle/src/Resources/contao/drivers/DC_Table.php(313): Contao\DC_Table::showAll
#15 /vendor/contao/core-bundle/src/Resources/contao/classes/Backend.php(667): Contao\Backend::getBackendModule
#14 /vendor/contao/core-bundle/src/Resources/contao/controllers/BackendMain.php(168): Contao\BackendMain::run
#13 /vendor/contao/core-bundle/src/Controller/BackendController.php(49): Contao\CoreBundle\Controller\BackendController::mainAction
#12 /vendor/symfony/http-kernel/HttpKernel.php(163): Symfony\Component\HttpKernel\HttpKernel::handleRaw
#11 /vendor/symfony/http-kernel/HttpKernel.php(75): Symfony\Component\HttpKernel\HttpKernel::handle
#10 /vendor/symfony/http-kernel/Kernel.php(202): Symfony\Component\HttpKernel\Kernel::handle
#9 /vendor/symfony/http-kernel/HttpCache/SubRequestHandler.php(86): Symfony\Component\HttpKernel\HttpCache\SubRequestHandler::handle
#8 /vendor/symfony/http-kernel/HttpCache/HttpCache.php(481): Symfony\Component\HttpKernel\HttpCache\HttpCache::forward
#7 /vendor/symfony/framework-bundle/HttpCache/HttpCache.php(73): Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache::forward
#6 /vendor/symfony/http-kernel/HttpCache/HttpCache.php(454): Symfony\Component\HttpKernel\HttpCache\HttpCache::fetch
#5 /vendor/contao/manager-bundle/src/HttpKernel/ContaoCache.php(66): Contao\ManagerBundle\HttpKernel\ContaoCache::fetch
#4 /vendor/symfony/http-kernel/HttpCache/HttpCache.php(348): Symfony\Component\HttpKernel\HttpCache\HttpCache::lookup
#3 /vendor/symfony/http-kernel/HttpCache/HttpCache.php(226): Symfony\Component\HttpKernel\HttpCache\HttpCache::handle
#2 /vendor/friendsofsymfony/http-cache/src/SymfonyCache/EventDispatchingHttpCache.php(96): Contao\ManagerBundle\HttpKernel\ContaoCache::handle
#1 /web/index.php(44): require
#0 /web/app.php(13): null
```

This is because `$GLOBALS['TL_KEYWORDS']` is only initialised in the front end within `PageRegular::prepare()`. This PR simply ignores it if not set.

Commits
-------

e54dc2b8 fix warning when legacy keywords are present
leofeyer pushed a commit that referenced this pull request Jun 7, 2024
…#7268)

Description
-----------

Got this erro in my logs:

```
RuntimeException: The Symfony container is not available, did you initialize the Contao framework? in vendor/contao/core-bundle/contao/library/Contao/System.php:143 Stack trace:
#0 vendor/contao/core-bundle/contao/library/Contao/System.php(97): Contao\System->import('Contao\\Config', 'Config')
#1 vendor/contao/core-bundle/contao/library/Contao/DcaExtractor.php(105): Contao\System->__construct()
#2 vendor/contao/core-bundle/contao/library/Contao/DcaExtractor.php(140): Contao\DcaExtractor->__construct('tl_opt_in')
#3 vendor/contao/core-bundle/contao/library/Contao/Model.php(291): Contao\DcaExtractor::getInstance('tl_opt_in')
#4 vendor/contao/core-bundle/contao/library/Contao/Model.php(1084): Contao\Model::getUniqueFields()
#5 vendor/contao/core-bundle/contao/models/OptInModel.php(87): Contao\Model::findBy(Array, 1716888783, Array)
#6 vendor/contao/core-bundle/src/Framework/Adapter.php(38): Contao\OptInModel::findExpiredTokens()
#7 vendor/contao/core-bundle/src/OptIn/OptIn.php(76): Contao\CoreBundle\Framework\Adapter->__call('findExpiredToke...', Array)
#8 vendor/contao/core-bundle/src/Cron/PurgeOptInTokensCron.php(30): Contao\CoreBundle\OptIn\OptIn->purgeTokens()
#9 vendor/contao/core-bundle/src/Cron/CronJob.php(44): Contao\CoreBundle\Cron\PurgeOptInTokensCron->__invoke('cli')
#10 vendor/contao/core-bundle/src/Cron/Cron.php(197): Contao\CoreBundle\Cron\CronJob->__invoke('cli')
#11 vendor/contao/core-bundle/src/Cron/Cron.php(182): Contao\CoreBundle\Cron\Cron->executeCrons(Array, 'cli', Object(Closure))
#12 vendor/contao/core-bundle/src/Cron/Cron.php(97): Contao\CoreBundle\Cron\Cron->doRun(Array, 'cli', false)
#13 vendor/contao/core-bundle/src/Command/CronCommand.php(53): Contao\CoreBundle\Cron\Cron->run('cli', false)
#14 vendor/symfony/console/Command/Command.php(326): Contao\CoreBundle\Command\CronCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 vendor/symfony/console/Application.php(1096): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#16 vendor/symfony/framework-bundle/Console/Application.php(126): Symfony\Component\Console\Application->doRunCommand(Object(Contao\CoreBundle\Command\CronCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#17 vendor/symfony/console/Application.php(324): Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand(Object(Contao\CoreBundle\Command\CronCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#18 vendor/symfony/framework-bundle/Console/Application.php(80): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#19 vendor/symfony/console/Application.php(175): Symfony\Bundle\FrameworkBundle\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#20 vendor/contao/manager-bundle/bin/contao-console(40): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput))
#21 vendor/bin/contao-console(119):  #22
```

Commits
-------

9ee76a07 Initialize the Contao framework when working with opt-in tokens
leofeyer added a commit that referenced this pull request Sep 9, 2024
Description
-----------

Fixes #6981

### Before

<img width="830" alt="" src="https://github.com/user-attachments/assets/22678211-70f9-4923-84f6-e1798b456e93">

### After

<img width="831" alt="" src="https://github.com/user-attachments/assets/811a7e1f-4443-40d7-ac56-a58db668f32b">

Commits
-------

22d12519 Correctly handle news feed URLs in the page routing listener
ccd99308 Adjust the implementation as suggested
c924cde6 Get the URL prefix and suffix from the route configuration
0801c856 Fix the tests
50d107ef Simplify the tests
c321d1a3 Check `isRoutable()` before calling `getRoute()`
442411ba Use the static prefix (see #16)
e092ade3 Return early if the current page is not routable
5b656d55 Add a test for the early return if a page is not routable

Co-authored-by: aschempp <andreas.schempp@terminal42.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants