netzmacht / contao-page-context
这个库提供了一些工具,用于为自定义路由启动Contao页面上下文。
1.2.1
2024-02-07 15:38 UTC
Requires
- php: ^8.1
- beberlei/assert: ^2.7 || ^3.0
- contao/core-bundle: ^4.13 || ^5.2
- netzmacht/contao-toolkit: ^3.9 || ^4.0
- psr/log: ^1.0 || ^2.0 || ^3.0
- symfony/config: ^5.4 || ^6.0
- symfony/dependency-injection: ^5.4 || ^6.0
- symfony/http-foundation: ^5.4 || ^6.0
- symfony/http-kernel: ^5.4 || ^6.0
- symfony/security-core: ^5.4 || ^6.0
- symfony/translation-contracts: ^1.1 || ^2.0 || ^3.0
Requires (Dev)
- contao/manager-plugin: ^2.0
- doctrine/coding-standard: ^12.0
- friends-of-phpspec/phpspec-expect: ^4.0
- netzmacht/phpspec-phpcq-plugin: @dev
- phpcq/runner-bootstrap: ^1.0@dev
- phpspec/phpspec: ^7.0
This package is auto-updated.
Last update: 2024-09-07 16:59:18 UTC
README
这个Contao扩展允许开发者在使用自定义路由时手动启动Contao的页面上下文。
Contao CMS的一些部分依赖于在渲染页面时初始化的全局状态。模块、内容元素、插入标记和自定义扩展可能会依赖于这种状态已初始化。
例如,Contao开发者通过访问$GLOBALS['objPage']
来获取当前页面,因为没有其他方法可以获取当前页面。
然而,当使用自定义入口点,例如API时,您没有初始化这种状态。使用Contao库和功能可能会导致意外的错误。
这正是这个扩展介入的地方。它允许您为您的路由手动启动页面上下文。
具体来说,它初始化以下步骤:
- Contao框架
- 如果未定义,将常量
BE_USER_LOGGED_IN
和FE_USER_LOGGED_IN
设置为false
。 - 从数据库中加载页面
- 全局变量
objPage
、TL_ADMIN_NAME
、TL_ADMIN_EMAIL
、TL_KEYWORDS
、TL_LANGUAGE
- 初始化请求的本地化和翻译器
- 加载默认语言文件
- 调用
Controller::initializeStaticUrls()
- 初始化页面布局(触发
getPageLayout
钩子)
要求
- Contao
^4.9
- PHP
^7.1 || ^8.0
安装
php composer.phar require netzmacht/contao-page-context --update-no-dev -o
使用
1. 实现一个PageIdDeterminator并正确注册它
首先,您必须提供一个PageIdDeterminator。它负责从给定的请求中提取页面ID。
您应该将确定器限制到您的特殊用例,这就是为什么存在match()
方法。
<?php declare(strict_types=1); namespace My\Bundle; use Netzmacht\Contao\PageContext\Request\PageIdDeterminator; use Netzmacht\Contao\PageContext\Exception\DeterminePageIdFailed; use Symfony\Component\HttpFoundation\Request; final class MyPageIdDeterminator implements PageIdDeterminator { public function match(Request $request): bool { return ($request->attributes->get('_my_context') === 'page'); } public function determinate(Request $request): int { if (!$request->attributes->has('pageId')) { throw new DeterminePageIdFailed('Could not determine page id for from request.'); } return $request->attributes->getInt('pageId'); } }
现在,您必须将其注册为服务,并标记为Netzmacht\Contao\PageContext\Request\PageIdDeterminator
。
<?xml version="1.0" encoding="UTF-8" ?> <container xmlns="https://symfony.ac.cn/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://symfony.ac.cn/schema/dic/services https://symfony.ac.cn/schema/dic/services/services-1.0.xsd"> <services> <service id="My\Bundle\MyPageIdDeterminator"> <tag name="Netzmacht\Contao\PageContext\Request\PageIdDeterminator" /> </service> </services> </container>
2. 准备您的路由
如上面示例所示,已访问自定义路由属性,这里是_my_context
。您应该在路由配置中定义它
<?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="https://symfony.ac.cn/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://symfony.ac.cn/schema/routing https://symfony.ac.cn/schema/routing/routing-1.0.xsd"> <route id="my_route" controller="My\Bundle\Action\ApiAction" path="/my/api/{pageId}" > <default key="_my_context">page</default> <default key="_scope">frontend</default> <requirement key="pageId">\d+</requirement> </route> </routes>
3. 访问页面对象
这就完成了。如果您尝试访问$GLOBALS['objPage']
,您应该有页面对象。好消息是,您可以避免访问全局状态。您的当前请求有一个新属性,称为_page_context
。
<?php declare(strict_types=1); namespace My\Bundle\Action; use Netzmacht\Contao\PageContext\Request\PageContext; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; final class ApiAction { public function __invoke(Request $request): Response { /** @var PageContext $context */ $context = $request->attributes->get('_page_context'); return new JsonResponse( [ 'pageId' => $context->page()->id, 'rootId' => $context->rootPage()->id, ] ); } }