From c339f752b5a9de9563975d92d5a66b8c60c74791 Mon Sep 17 00:00:00 2001 From: Leo Feyer Date: Mon, 7 Oct 2019 23:26:38 +0200 Subject: [PATCH] Make the SERP preview a widget --- .../src/EventListener/InsertTagsListener.php | 10 +- .../PreviewUrlConvertListener.php | 6 +- .../src/Resources/contao/classes/Events.php | 7 +- .../contao/dca/tl_calendar_events.php | 39 +--- .../contao/models/CalendarEventsModel.php | 100 ++++++++++- .../EventListener/InsertTagsListenerTest.php | 22 +-- .../PreviewUrlConverterListenerTest.php | 7 +- .../src/Resources/contao/config/config.php | 3 +- .../src/Resources/contao/dca/tl_page.php | 38 +--- .../Resources/contao/languages/en/default.xlf | 4 +- .../Resources/contao/library/Contao/Model.php | 2 +- .../contao/library/Contao/Model/Routable.php | 28 +++ .../src/Resources/contao/models/PageModel.php | 16 +- .../contao/templates/backend/be_serp.html5 | 27 --- .../Resources/contao/themes/flexible/main.css | 5 +- .../contao/themes/flexible/main.min.css | 2 +- .../Resources/contao/widgets/SerpPreview.php | 169 ++++++++++++++++++ .../src/EventListener/InsertTagsListener.php | 10 +- .../PreviewUrlConvertListener.php | 6 +- .../src/Resources/contao/classes/News.php | 5 + .../src/Resources/contao/dca/tl_news.php | 39 +--- .../src/Resources/contao/models/NewsModel.php | 100 ++++++++++- .../Resources/contao/modules/ModuleNews.php | 23 ++- .../EventListener/InsertTagsListenerTest.php | 22 +-- .../PreviewUrlConverterListenerTest.php | 7 +- 25 files changed, 485 insertions(+), 212 deletions(-) create mode 100644 core-bundle/src/Resources/contao/library/Contao/Model/Routable.php delete mode 100644 core-bundle/src/Resources/contao/templates/backend/be_serp.html5 create mode 100644 core-bundle/src/Resources/contao/widgets/SerpPreview.php diff --git a/calendar-bundle/src/EventListener/InsertTagsListener.php b/calendar-bundle/src/EventListener/InsertTagsListener.php index 79a4b0f6acc..e388b1888f3 100644 --- a/calendar-bundle/src/EventListener/InsertTagsListener.php +++ b/calendar-bundle/src/EventListener/InsertTagsListener.php @@ -15,7 +15,6 @@ use Contao\CalendarEventsModel; use Contao\CalendarFeedModel; use Contao\CoreBundle\Framework\ContaoFramework; -use Contao\Events; use Contao\StringUtil; class InsertTagsListener @@ -82,14 +81,11 @@ private function replaceEventInsertTag(string $insertTag, string $idOrAlias, arr return ''; } - /** @var Events $events */ - $events = $this->framework->getAdapter(Events::class); - switch ($insertTag) { case 'event': return sprintf( '%s', - $events->generateEventUrl($model, \in_array('absolute', $flags, true)), + \in_array('absolute', $flags, true) ? $model->getAbsoluteUrl() : $model->getFrontendUrl(), StringUtil::specialchars($model->title), $model->title ); @@ -97,12 +93,12 @@ private function replaceEventInsertTag(string $insertTag, string $idOrAlias, arr case 'event_open': return sprintf( '', - $events->generateEventUrl($model, \in_array('absolute', $flags, true)), + \in_array('absolute', $flags, true) ? $model->getAbsoluteUrl() : $model->getFrontendUrl(), StringUtil::specialchars($model->title) ); case 'event_url': - return $events->generateEventUrl($model, \in_array('absolute', $flags, true)); + return \in_array('absolute', $flags, true) ? $model->getAbsoluteUrl() : $model->getFrontendUrl(); case 'event_title': return StringUtil::specialchars($model->title); diff --git a/calendar-bundle/src/EventListener/PreviewUrlConvertListener.php b/calendar-bundle/src/EventListener/PreviewUrlConvertListener.php index 785f3a8ae8c..1964a3a68cd 100644 --- a/calendar-bundle/src/EventListener/PreviewUrlConvertListener.php +++ b/calendar-bundle/src/EventListener/PreviewUrlConvertListener.php @@ -15,7 +15,6 @@ use Contao\CalendarEventsModel; use Contao\CoreBundle\Event\PreviewUrlConvertEvent; use Contao\CoreBundle\Framework\ContaoFramework; -use Contao\Events; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -52,10 +51,7 @@ public function onPreviewUrlConvert(PreviewUrlConvertEvent $event): void return; } - /** @var Events $eventsAdapter */ - $eventsAdapter = $this->framework->getAdapter(Events::class); - - $event->setUrl($request->getSchemeAndHttpHost().'/'.$eventsAdapter->generateEventUrl($eventModel)); + $event->setUrl($request->getSchemeAndHttpHost().'/'.$eventModel->getFrontendUrl()); } private function getEventModel(Request $request): ?CalendarEventsModel diff --git a/calendar-bundle/src/Resources/contao/classes/Events.php b/calendar-bundle/src/Resources/contao/classes/Events.php index 84e1d21632a..13907bc3bc0 100644 --- a/calendar-bundle/src/Resources/contao/classes/Events.php +++ b/calendar-bundle/src/Resources/contao/classes/Events.php @@ -306,7 +306,7 @@ protected function addEvent($objEvents, $intStart, $intEnd, $intBegin, $intLimit $arrEvent['link'] = $objEvents->title; $arrEvent['target'] = ''; $arrEvent['title'] = StringUtil::specialchars($objEvents->title, true); - $arrEvent['href'] = $this->generateEventUrl($objEvents); + $arrEvent['href'] = $objEvents->current()->getFrontendUrl(); $arrEvent['class'] = $objEvents->cssClass ? ' ' . $objEvents->cssClass : ''; $arrEvent['recurring'] = $recurring; $arrEvent['until'] = $until; @@ -418,9 +418,14 @@ protected function addEvent($objEvents, $intStart, $intEnd, $intBegin, $intLimit * @param boolean $blnAbsolute * * @return string + * + * @deprecated Deprecated since Contao 4.9, to be removed in Contao 5.0; + * use CalendardEventsModel::getFrontendUrl() instead */ public static function generateEventUrl($objEvent, $blnAbsolute=false) { + @trigger_error('Using Events::generateEventUrl() has been deprecated and will no longer work in Contao 5.0. Use CalendardEventsModel::getFrontendUrl() instead.', E_USER_DEPRECATED); + $strCacheKey = 'id_' . $objEvent->id . ($blnAbsolute ? '_absolute' : ''); // Load the URL from cache diff --git a/calendar-bundle/src/Resources/contao/dca/tl_calendar_events.php b/calendar-bundle/src/Resources/contao/dca/tl_calendar_events.php index 6ea32c25e8f..51f420dd541 100644 --- a/calendar-bundle/src/Resources/contao/dca/tl_calendar_events.php +++ b/calendar-bundle/src/Resources/contao/dca/tl_calendar_events.php @@ -117,7 +117,7 @@ 'palettes' => array ( '__selector__' => array('addTime', 'addImage', 'recurring', 'addEnclosure', 'source', 'overwriteMeta'), - 'default' => '{title_legend},title,alias,author;{date_legend},addTime,startDate,endDate;{meta_legend},pageTitle,description,serp_preview;{details_legend},location,address,teaser;{image_legend},addImage;{recurring_legend},recurring;{enclosure_legend:hide},addEnclosure;{source_legend:hide},source;{expert_legend:hide},cssClass,noComments;{publish_legend},published,start,stop' + 'default' => '{title_legend},title,alias,author;{date_legend},addTime,startDate,endDate;{meta_legend},pageTitle,description,serpPreview;{details_legend},location,address,teaser;{image_legend},addImage;{recurring_legend},recurring;{enclosure_legend:hide},addEnclosure;{source_legend:hide},source;{expert_legend:hide},cssClass,noComments;{publish_legend},published,start,stop' ), // Subpalettes @@ -254,11 +254,12 @@ 'eval' => array('style'=>'height:60px', 'decodeEntities'=>true, 'tl_class'=>'clr'), 'sql' => "text NULL" ), - 'serp_preview' => array + 'serpPreview' => array ( - 'label' => &$GLOBALS['TL_LANG']['MSC']['serp_preview'], + 'label' => &$GLOBALS['TL_LANG']['MSC']['serpPreview'], 'exclude' => true, - 'input_field_callback' => array('tl_calendar_events', 'showSerpPreview') + 'inputType' => 'serpPreview', + 'eval' => array('serpPreview'=>array('title'=>array('pageTitle', 'title'), 'description'=>array('description', 'teaser'))), ), 'location' => array ( @@ -813,36 +814,6 @@ public function getArticleAlias(Contao\DataContainer $dc) return $arrAlias; } - /** - * Show the SERP preview - * - * @param Contao\DataContainer $dc - * - * @return string - */ - public function showSerpPreview(Contao\DataContainer $dc) - { - $event = Contao\CalendarEventsModel::findByPk($dc->activeRecord->id); - $url = Contao\Events::generateEventUrl($event, true); - $suffix = substr($dc->inputName, strlen($dc->field)); - - list($baseUrl) = explode($event->alias ?: $event->id, $url); - - $template = new Contao\FrontendTemplate('be_serp'); - $template->id = $event->id; - $template->title = $event->pageTitle ?: $event->title; - $template->url = $url; - $template->description = $event->description ?: strip_tags($event->teaser); - $template->baseUrl = $baseUrl; - $template->titleField = 'ctrl_pageTitle' . $suffix; - $template->titleFallbackField = 'ctrl_title' . $suffix; - $template->aliasField = 'ctrl_alias' . $suffix; - $template->descriptionField = 'ctrl_description' . $suffix; - $template->descriptionFallbackField = 'ctrl_teaser' . $suffix; - - return $template->parse(); - } - /** * Add the source options depending on the allowed fields (see #5498) * diff --git a/calendar-bundle/src/Resources/contao/models/CalendarEventsModel.php b/calendar-bundle/src/Resources/contao/models/CalendarEventsModel.php index 2836e6a1095..2817a9e7a5f 100644 --- a/calendar-bundle/src/Resources/contao/models/CalendarEventsModel.php +++ b/calendar-bundle/src/Resources/contao/models/CalendarEventsModel.php @@ -11,6 +11,7 @@ namespace Contao; use Contao\Model\Collection; +use Contao\Model\Routable; /** * Reads and writes events @@ -190,7 +191,7 @@ * * @author Leo Feyer */ -class CalendarEventsModel extends Model +class CalendarEventsModel extends Model implements Routable { /** * Table name @@ -198,6 +199,16 @@ class CalendarEventsModel extends Model */ protected static $strTable = 'tl_calendar_events'; + /** + * @var string + */ + private $strFrontendUrl; + + /** + * @var string + */ + private $strAbsoluteUrl; + /** * Find a published event from one or more calendars by its ID or alias * @@ -320,6 +331,93 @@ public static function findUpcomingByPids($arrIds, $intLimit=0, array $arrOption return static::findBy($arrColumns, null, $arrOptions); } + + /** + * {@inheritdoc} + */ + public function getFrontendUrl() + { + if (!$this->strFrontendUrl) + { + $this->strFrontendUrl = $this->getUrl('getFrontendUrl'); + } + + return $this->strFrontendUrl; + } + + /** + * {@inheritdoc} + */ + public function getAbsoluteUrl() + { + if (!$this->strAbsoluteUrl) + { + $this->strAbsoluteUrl = $this->getUrl('getAbsoluteUrl'); + } + + return $this->strAbsoluteUrl; + } + + /** + * Reset the URLs if the record is refreshed + * + * @param integer $intType + */ + public function refresh() + { + parent::refresh(); + + $this->strFrontendUrl = null; + $this->strAbsoluteUrl = null; + } + + /** + * Return the URL depending on the source + * + * @param $strMethod + * + * @return string + */ + private function getUrl($strMethod) + { + switch ($this->source) + { + // Link to an external page + case 'external': + if (0 === strncmp($this->url, 'mailto:', 7)) + { + return StringUtil::encodeEmail($this->url); + } + + return ampersand($this->url); + + // Link to an internal page + case 'internal': + if (($objTarget = $this->getRelated('jumpTo')) instanceof PageModel) + { + return $objTarget->$strMethod(); + } + break; + + // Link to an article + case 'article': + if (($objArticle = ArticleModel::findByPk($this->articleId)) instanceof ArticleModel && ($objPid = $objArticle->getRelated('pid')) instanceof PageModel) + { + return $objPid->$strMethod('/articles/' . ($objArticle->alias ?: $objArticle->id)); + } + break; + } + + // Link to the default page + $objPage = PageModel::findByPk($this->getRelated('pid')->jumpTo); + + if (!$objPage instanceof PageModel) + { + return ampersand(Environment::get('request')); + } + + return $objPage->$strMethod((Config::get('useAutoItem') ? '/' : '/events/') . ($this->alias ?: $this->id)); + } } class_alias(CalendarEventsModel::class, 'CalendarEventsModel'); diff --git a/calendar-bundle/tests/EventListener/InsertTagsListenerTest.php b/calendar-bundle/tests/EventListener/InsertTagsListenerTest.php index dcf821c9fd2..0a5e40f09ef 100644 --- a/calendar-bundle/tests/EventListener/InsertTagsListenerTest.php +++ b/calendar-bundle/tests/EventListener/InsertTagsListenerTest.php @@ -15,7 +15,6 @@ use Contao\CalendarBundle\EventListener\InsertTagsListener; use Contao\CalendarEventsModel; use Contao\CalendarFeedModel; -use Contao\Events; use Contao\TestCase\ContaoTestCase; use PHPUnit\Framework\MockObject\MockObject; @@ -47,23 +46,18 @@ public function testReplacesTheEventTags(): void $eventModel->title = 'The "foobar" event'; $eventModel->teaser = '

The annual foobar event.

'; - $events = $this->mockAdapter(['generateEventUrl']); - $events - ->method('generateEventUrl') - ->willReturnCallback( - static function (CalendarEventsModel $model, bool $absolute): string { - if ($absolute) { - return 'http://domain.tld/events/the-foobar-event.html'; - } - - return 'events/the-foobar-event.html'; - } - ) + $eventModel + ->method('getFrontendUrl') + ->willReturn('events/the-foobar-event.html') + ; + + $eventModel + ->method('getAbsoluteUrl') + ->willReturn('http://domain.tld/events/the-foobar-event.html') ; $adapters = [ CalendarEventsModel::class => $this->mockConfiguredAdapter(['findByIdOrAlias' => $eventModel]), - Events::class => $events, ]; $listener = new InsertTagsListener($this->mockContaoFramework($adapters)); diff --git a/calendar-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php b/calendar-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php index 224e9a42e7f..6c5bae5c97e 100644 --- a/calendar-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php +++ b/calendar-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php @@ -16,7 +16,6 @@ use Contao\CalendarEventsModel; use Contao\CoreBundle\Event\PreviewUrlConvertEvent; use Contao\CoreBundle\Framework\ContaoFramework; -use Contao\Events; use Contao\TestCase\ContaoTestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -34,10 +33,14 @@ public function testConvertsThePreviewUrl(): void $requestStack->push($request); $eventModel = $this->createMock(CalendarEventsModel::class); + $eventModel + ->expects($this->once()) + ->method('getFrontendUrl') + ->willReturn('events/winter-holidays.html') + ; $adapters = [ CalendarEventsModel::class => $this->mockConfiguredAdapter(['findByPk' => $eventModel]), - Events::class => $this->mockConfiguredAdapter(['generateEventUrl' => 'events/winter-holidays.html']), ]; $framework = $this->mockContaoFramework($adapters); diff --git a/core-bundle/src/Resources/contao/config/config.php b/core-bundle/src/Resources/contao/config/config.php index 1f7cd9932ac..b922ce881eb 100644 --- a/core-bundle/src/Resources/contao/config/config.php +++ b/core-bundle/src/Resources/contao/config/config.php @@ -233,7 +233,8 @@ 'imageSize' => 'Contao\ImageSize', 'timePeriod' => 'Contao\TimePeriod', 'metaWizard' => 'Contao\MetaWizard', - 'sectionWizard' => 'Contao\SectionWizard' + 'sectionWizard' => 'Contao\SectionWizard', + 'serpPreview' => 'Contao\SerpPreview' ); // Front end form fields diff --git a/core-bundle/src/Resources/contao/dca/tl_page.php b/core-bundle/src/Resources/contao/dca/tl_page.php index f43a6645df1..ea8e2d5591a 100644 --- a/core-bundle/src/Resources/contao/dca/tl_page.php +++ b/core-bundle/src/Resources/contao/dca/tl_page.php @@ -153,7 +153,7 @@ ( '__selector__' => array('type', 'fallback', 'autoforward', 'protected', 'createSitemap', 'includeLayout', 'includeCache', 'includeChmod', 'enforceTwoFactor'), 'default' => '{title_legend},title,alias,type', - 'regular' => '{title_legend},title,alias,type;{meta_legend},pageTitle,robots,description,serp_preview;{protected_legend:hide},protected;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide,noSearch,guests,requireItem;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', + 'regular' => '{title_legend},title,alias,type;{meta_legend},pageTitle,robots,description,serpPreview;{protected_legend:hide},protected;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide,noSearch,guests,requireItem;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', 'forward' => '{title_legend},title,alias,type;{meta_legend},pageTitle;{redirect_legend},jumpTo,redirect;{protected_legend:hide},protected;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide,guests;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', 'redirect' => '{title_legend},title,alias,type;{meta_legend},pageTitle;{redirect_legend},redirect,url,target;{protected_legend:hide},protected;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide,guests;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', 'root' => '{title_legend},title,alias,type;{meta_legend},pageTitle;{dns_legend},dns,useSSL,language,fallback;{global_legend:hide},dateFormat,timeFormat,datimFormat,adminEmail,staticFiles,staticPlugins;{alias_legend:hide},validAliasCharacters,useFolderUrl;{sitemap_legend:hide},createSitemap;{protected_legend:hide},protected;{layout_legend},includeLayout;{twoFactor_legend:hide},enforceTwoFactor;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{publish_legend},published,start,stop', @@ -264,11 +264,12 @@ 'eval' => array('style'=>'height:60px', 'decodeEntities'=>true, 'tl_class'=>'clr'), 'sql' => "text NULL" ), - 'serp_preview' => array + 'serpPreview' => array ( - 'label' => &$GLOBALS['TL_LANG']['MSC']['serp_preview'], + 'label' => &$GLOBALS['TL_LANG']['MSC']['serpPreview'], 'exclude' => true, - 'input_field_callback' => array('tl_page', 'showSerpPreview') + 'inputType' => 'serpPreview', + 'eval' => array('serpPreview'=>array('title'=>array('pageTitle', 'title'))) ), 'redirect' => array ( @@ -1287,35 +1288,6 @@ public function checkJumpTo($varValue, Contao\DataContainer $dc) return $varValue; } - /** - * Show the SERP preview - * - * @param Contao\DataContainer $dc - * - * @return string - */ - public function showSerpPreview(Contao\DataContainer $dc) - { - $page = Contao\PageModel::findByPk($dc->activeRecord->id); - $url = $page->getAbsoluteUrl(); - $suffix = substr($dc->inputName, strlen($dc->field)); - - list($baseUrl) = explode($page->alias ?: $page->id, $url); - - $template = new Contao\FrontendTemplate('be_serp'); - $template->id = $page->id; - $template->title = $page->pageTitle ?: $page->title; - $template->url = $url; - $template->description = $page->description; - $template->baseUrl = $baseUrl; - $template->titleField = 'ctrl_pageTitle' . $suffix; - $template->titleFallbackField = 'ctrl_title' . $suffix; - $template->aliasField = 'ctrl_alias' . $suffix; - $template->descriptionField = 'ctrl_description' . $suffix; - - return $template->parse(); - } - /** * Check the DNS settings * diff --git a/core-bundle/src/Resources/contao/languages/en/default.xlf b/core-bundle/src/Resources/contao/languages/en/default.xlf index 559e45732dd..eb3494b1eea 100644 --- a/core-bundle/src/Resources/contao/languages/en/default.xlf +++ b/core-bundle/src/Resources/contao/languages/en/default.xlf @@ -1847,10 +1847,10 @@ The internal CSS editor has been deprecated and will be removed in one of the next Contao versions! Please consider exporting your existing style sheets and re-adding them to the page layout as external style sheets. - + SERP preview - + Here you can preview the meta data in the search results. Some search engines might show longer texts or crop at a different position. diff --git a/core-bundle/src/Resources/contao/library/Contao/Model.php b/core-bundle/src/Resources/contao/library/Contao/Model.php index adb087a2a48..0b482fd35f9 100644 --- a/core-bundle/src/Resources/contao/library/Contao/Model.php +++ b/core-bundle/src/Resources/contao/library/Contao/Model.php @@ -414,7 +414,7 @@ public function current() public function save() { // Deprecated call - if (\count(\func_get_args())) + if (\func_num_args() > 0) { throw new \InvalidArgumentException('The $blnForceInsert argument has been removed (see system/docs/UPGRADE.md)'); } diff --git a/core-bundle/src/Resources/contao/library/Contao/Model/Routable.php b/core-bundle/src/Resources/contao/library/Contao/Model/Routable.php new file mode 100644 index 00000000000..787dcc511ab --- /dev/null +++ b/core-bundle/src/Resources/contao/library/Contao/Model/Routable.php @@ -0,0 +1,28 @@ + */ -class PageModel extends Model +class PageModel extends Model implements Routable { /** * Table name @@ -1064,12 +1065,7 @@ public function loadDetails() } /** - * Generate a front end URL - * - * @param string $strParams An optional string of URL parameters - * @param string $strForceLang Force a certain language - * - * @return string An URL that can be used in the front end + * {@inheritdoc} */ public function getFrontendUrl($strParams=null, $strForceLang=null) { @@ -1103,11 +1099,7 @@ public function getFrontendUrl($strParams=null, $strForceLang=null) } /** - * Generate an absolute URL depending on the current rewriteURL setting - * - * @param string $strParams An optional string of URL parameters - * - * @return string An absolute URL that can be used in the front end + * {@inheritdoc} */ public function getAbsoluteUrl($strParams=null) { diff --git a/core-bundle/src/Resources/contao/templates/backend/be_serp.html5 b/core-bundle/src/Resources/contao/templates/backend/be_serp.html5 deleted file mode 100644 index 82472bd32af..00000000000 --- a/core-bundle/src/Resources/contao/templates/backend/be_serp.html5 +++ /dev/null @@ -1,27 +0,0 @@ - -
-

trans('MSC.serp_preview.0') ?>

-
-

title, 64) ?>

-

url ?>

-

description, 160) ?>

-
- -

trans('MSC.serp_preview.1') ?>

- -
- - diff --git a/core-bundle/src/Resources/contao/themes/flexible/main.css b/core-bundle/src/Resources/contao/themes/flexible/main.css index 8a264b7b4a6..99c5e12a1b7 100644 --- a/core-bundle/src/Resources/contao/themes/flexible/main.css +++ b/core-bundle/src/Resources/contao/themes/flexible/main.css @@ -1505,12 +1505,9 @@ ul.sgallery li { } /* SERP preview */ -.serp { - margin-top:1px; -} .serp-preview { max-width:600px; - margin:1px 0 2px; + margin:2px 0; padding:4px 6px; font-family:Arial,sans-serif; font-weight:400; diff --git a/core-bundle/src/Resources/contao/themes/flexible/main.min.css b/core-bundle/src/Resources/contao/themes/flexible/main.min.css index 82b28154e1b..21ee2dab16d 100644 --- a/core-bundle/src/Resources/contao/themes/flexible/main.min.css +++ b/core-bundle/src/Resources/contao/themes/flexible/main.min.css @@ -1 +1 @@ -body{background:#cfcfd3;overflow-y:scroll}body.popup{background:#fff}#header{min-height:40px;text-align:left}#header .inner{background:#f47c00}body:not(.fullscreen) #header .inner{max-width:1440px;margin:0 auto}#header,#header a{color:#fff}#header h1{position:absolute}#header h1 a{display:block;padding:12px 12px 12px 43px;background:url(icons/logo.svg) no-repeat 10px center;font-weight:400}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#header h1 a{font-weight:300}}#tmenu{display:flex;justify-content:flex-end}#tmenu li{position:relative}#tmenu a,#tmenu h2{padding:13px 12px;display:inline-block}#tmenu img{vertical-align:top}#tmenu sup{position:absolute;top:5px;left:20px;z-index:1;font-size:.6rem;background:#fff;padding:2px;border-radius:2px;text-indent:0;color:#f47c00;font-weight:400}#tmenu .burger{display:none}#tmenu .burger button{margin-right:-2px;padding:8px 10px 9px;background:0 0;border:0;vertical-align:top}#tmenu .burger img{margin-bottom:-1px}#tmenu h2{padding-right:26px;cursor:pointer;background:url(icons/chevron-down.svg) right 9px top 14px no-repeat;font-size:.875rem;font-weight:400;color:#fff}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tmenu h2{font-weight:300}}#tmenu a,#tmenu h2,#tmenu .burger button{transition:background-color .3s ease}#tmenu a:hover,#tmenu a.hover,#tmenu li:hover h2,#tmenu .active h2,#tmenu .burger button:hover{background-color:#e87600}#tmenu ul.level_2{min-width:150px;position:absolute;right:6px;margin-top:5px;padding:6px 0 9px;background:#fff;box-shadow:0 0 3px #999;z-index:1;color:#444;text-align:left;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease}#tmenu .active ul.level_2{opacity:1;visibility:visible}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tmenu ul.level_2{color:#222}}#tmenu ul.level_2 li a{display:block;color:inherit;padding:6px 20px 6px 40px;white-space:nowrap}#tmenu ul.level_2 li a:hover{background-color:#eee}#tmenu ul.level_2 .info{color:gray;padding:9px 20px 15px;border-bottom:1px solid #e6e6e8;line-height:1.4;margin-bottom:9px;white-space:nowrap}#tmenu ul.level_2 strong{color:#222;display:block}#tmenu ul.level_2:before{content:"";display:block;width:0;height:0;position:absolute;right:9px;top:-14px;border:7px solid transparent;border-bottom-color:#fff}#tmenu ul.level_2:after{content:"";display:block;width:100%;height:5px;position:absolute;top:-5px}#tmenu .icon-alert{width:16px;margin-bottom:-2px;position:relative;background:url(icons/alert.svg) center center no-repeat;overflow:hidden;white-space:nowrap;text-indent:28px}#tmenu .icon-profile{background:url(icons/profile_dark.svg) 20px center no-repeat}#tmenu .icon-security{background:url(icons/shield_dark.svg) 20px center no-repeat}#tmenu .icon-logout{background:url(icons/exit_dark.svg) 20px center no-repeat}#container{display:flex;min-height:calc(100vh - 40px);background:#cfcfd3}body:not(.fullscreen) #container{max-width:1440px;margin:0 auto}.popup #container{padding:0;width:auto;min-height:0;background:#fff;max-width:none}#left{float:left;width:225px;min-height:calc(100vh - 40px);background:#0f1c26;display:flex;flex-direction:column}#left .version{margin-top:4em;padding:15px;border-top:1px solid #3a454d;font-size:.75rem;line-height:1.4;background:#172b3b}#left .version,#left .version a{color:#9fa4a8}#main{float:left;width:calc(100% - 225px);min-height:calc(100vh - 40px);background:#eaeaec}.popup #main{float:none;width:auto;max-width:none;min-height:0;margin:0;padding:0;border:0;display:initial}#main .content{margin:15px;background:#fff;border:1px solid #d0d0d2}.popup #main .content{margin:0;border:0}#tl_navigation{flex-grow:1}#tl_navigation .tl_level_1_group{margin:0 15px;padding:15px 0 6px;border-top:1px solid #3a454d}#tl_navigation .tl_level_1_group:first-child{border-top:0;padding-top:18px}#tl_navigation .tl_level_1_group a{display:block;padding:3px 3px 3px 24px;color:#9fa4a8;font-size:.75rem;text-transform:uppercase}#tl_navigation .group-content{background:url(icons/content.svg) 3px 2px no-repeat}#tl_navigation .group-design{background:url(icons/monitor.svg) 3px 2px no-repeat}#tl_navigation .group-accounts{background:url(icons/person.svg) 3px 2px no-repeat}#tl_navigation .group-system{background:url(icons/wrench.svg) 3px 2px no-repeat}#tl_navigation .node-collapsed{padding-bottom:14px}#tl_navigation .tl_level_2{padding:0 0 15px}#tl_navigation .tl_level_2 li{border-left:4px solid #0f1c26}#tl_navigation .tl_level_2 li.active{background-color:#172b3b;border-left-color:#f47c00}#tl_navigation .tl_level_2 a{display:block;padding:6px 18px 6px 35px;font-weight:400;color:#d3d5d7;transition:color .2s ease}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tl_navigation .tl_level_2 a{font-weight:300}}#tl_navigation .tl_level_2 li:hover a{color:#fff}#tl_buttons{margin:0;padding:12px 15px;text-align:right}.toggleWrap{cursor:pointer}.opacity{-moz-opacity:.8;opacity:.8}#main_headline{margin:20px 0;padding:0 16px;font-size:1.1rem}.popup #main_headline{display:none}#main_headline span:nth-child(even){font-weight:400}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#main_headline span:nth-child(even){font-weight:300}}h2.sub_headline{margin:3px 18px;padding:7px 0}.tl_gerror{margin:12px;padding:3px 0 3px 22px;background:url(icons/error.svg) no-repeat left center}.tl_error,.tl_confirm,.tl_info,.tl_new{margin:0 0 1px;padding:11px 18px 11px 37px;line-height:1.3}.tl_error{background:#faebeb url(icons/error.svg) no-repeat 16px 12px}.tl_confirm{background:#eefcde url(icons/ok.svg) no-repeat 16px 12px}.tl_info{background:#e9f0f7 url(icons/show.svg) no-repeat 16px 12px}.tl_new{background:#fbf2e5 url(icons/featured.svg) no-repeat 16px 12px}.tl_gerror,.tl_gerror a,.tl_error,.tl_error a{color:#c33}.tl_confirm,.tl_confirm a{color:#589b0e}.tl_info,.tl_info a{color:#006494}.tl_new,.tl_new a{color:#d68c23}.tl_panel,.tl_version_panel{padding:8px 10px 8px 0;background:#f3f3f5;border-bottom:1px solid #ddd;text-align:right}.tl_version_panel .tl_select{max-width:280px}.tl_version_panel .tl_formbody{position:relative}.tl_img_submit{width:16px;height:16px;border:0;margin:0;padding:0;text-indent:16px;white-space:nowrap;overflow:hidden;position:relative;top:9px;vertical-align:top;cursor:pointer}.filter_apply{background:url(icons/filter-apply.svg) center center no-repeat}.filter_reset{background:url(icons/filter-reset.svg) center center no-repeat}.tl_subpanel{float:right;letter-spacing:-.31em}.tl_subpanel *{letter-spacing:normal}.tl_subpanel strong,.tl_search span{vertical-align:middle}.tl_submit_panel{min-width:32px;padding-left:6px;padding-right:3px}.tl_panel .active,.tl_panel_bottom .active,#search .active{background-color:#fffce1}.tl_filter{width:100%}.tl_filter .tl_select{max-width:14.65%;margin-left:3px}.tl_submit_panel+.tl_filter{width:86%}.tl_limit{width:22%}.tl_limit .tl_select{width:52%;margin-left:3px}.tl_search{width:40%}.tl_search .tl_select{width:38%;margin-left:3px;margin-right:1%}.tl_search .tl_text{width:30%;margin-left:1%;-webkit-appearance:textfield;box-sizing:content-box}.tl_sorting{width:26%}.tl_sorting .tl_select{width:60%;margin-left:1%}input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.tl_xpl{padding:0 18px}.tl_tbox,.tl_box{padding:12px 0 26px;border-bottom:1px solid #e6e6e8}.tl_tbox:last-child,.tl_box:last-child{border-bottom:0}.tl_box h3,.tl_tbox h3,.tl_xpl h3{margin:0;padding:14px 0 1px;font-size:.875rem}.tl_box h4,.tl_tbox h4{margin:6px 0 0;padding:0;font-size:.875rem}.tl_tbox.theme_import{padding-left:15px;padding-right:15px}.tl_tbox.theme_import h3,.tl_tbox.theme_import h4,.tl_tbox.theme_import p{line-height:1.3}.tl_help,.tl_help *{font-size:.75rem}.tl_help,.tl_help a{margin-bottom:0;line-height:1.25;color:gray}.tl_help a:hover,.tl_help a:focus,.tl_help a:active{text-decoration:underline}.tl_formbody_edit.nogrid .w50{float:none}.tl_formbody_edit.nogrid .m12{margin-top:0;margin-bottom:0}.tl_edit_form .tl_formbody_edit{border-top:1px solid #e6e6e8}.tl_formbody_submit{border-top:1px solid #ddd}.tl_submit_container{padding:8px 15px;background:#f3f3f5}.tl_submit_container .tl_submit{margin-top:2px;margin-bottom:2px}.maintenance_active{padding-top:12px}.maintenance_active,.maintenance_inactive{border-top:1px solid #e6e6e8}.maintenance_inactive:last-child{padding-bottom:9px}.maintenance_inactive .tl_tbox{border:0!important;padding:6px 15px 14px}.maintenance_inactive .tl_message{margin-top:0}.maintenance_inactive h2.sub_headline{margin:18px 15px 3px}.maintenance_inactive .tl_submit_container{background:0 0;padding:0 15px 24px;border:0}.maintenance_inactive:last-of-type .tl_submit_container{padding-bottom:10px}#tl_maintenance_mode .tl_message{margin-bottom:12px}#tl_maintenance_mode .tl_message>p{padding-top:0;padding-bottom:0;background-color:transparent;background-position-y:center}#tl_maintenance_index .tl_tbox{margin-top:-12px}.two-factor{border-top:1px solid #e6e6e8;padding-bottom:9px}.two-factor h2.sub_headline{margin:18px 15px 3px}.two-factor>p{margin:0 15px 12px;line-height:1.3}.two-factor li{margin-left:2em;list-style:initial}.two-factor .qr-code{margin:0 15px}.two-factor .widget{height:auto;margin:15px 15px 12px}.two-factor .widget .tl_error{margin:0;padding:1px 0;background:0 0;font-size:.75rem;line-height:1.25}.two-factor .tl_submit_container{background:0 0;padding:0 15px 10px;border:0}.two-factor .submit_container{clear:both;margin:0 15px 12px}.two-factor .tl_message{margin-bottom:12px}.two-factor .tl_message>p{padding-top:0;padding-bottom:0;background-color:transparent;background-position-y:center}#search{margin:18px 18px -9px;text-align:right}#search .tl_text{max-width:160px;-webkit-appearance:textfield;box-sizing:content-box}.tl_edit_preview{margin-top:18px}.tl_edit_preview img{max-width:100%;height:auto;padding:2px;border:1px solid #ddd;background:#fff}.tl_edit_preview_enabled{position:relative;cursor:crosshair;display:inline-block}.tl_edit_preview_important_part{position:absolute;margin:-1px;border:1px solid #000;box-shadow:0 0 0 1px #fff,inset 0 0 0 1px #fff;opacity:.5}#tl_rebuild_index{padding:0 18px 18px;line-height:1.3}#index_note{margin:24px 0 18px;padding:11px 12px 12px;background:#ffc;border:1px solid #f90;font-size:.875rem}#index_loading{margin:0;padding:12px 12px 12px 24px;background:url(icons/loading.svg) no-repeat left center;background-size:16px;color:#006494}#index_complete{margin:0;padding:12px 12px 12px 24px;background:url(icons/ok.svg) no-repeat left center;color:#589b0e}table.tl_listing{width:100%}.tl_listing_container{padding:2px 0;margin:20px 15px 16px}.tl_listing_container.tree_view{position:relative}#tl_buttons+.tl_listing_container{margin-top:10px}#paste_hint+.tl_listing_container{margin-top:30px}.tl_folder_list,.tl_folder_tlist{padding:7px 0;border-bottom:1px solid #e9e9e9;background:#f3f3f5;font-weight:600}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_folder_list,.tl_folder_tlist{font-weight:500}}.tl_folder_tlist{border-top:1px solid #e9e9e9}.tl_file,.tl_file_list{padding:5px 0;border-bottom:1px solid #e9e9e9;background:#fff}.tl_file_list{padding:7px 0}.tl_file_list .ellipsis{height:15px;text-overflow:ellipsis;overflow:hidden;padding-right:18px;word-break:break-all}.tl_right_nowrap{padding:3px 0;text-align:right;white-space:nowrap}.tl_listing.picker .tl_file,.tl_listing.picker .tl_folder,.tl_listing.picker .tl_right_nowrap,.tl_listing_container.picker .tl_content_header,.tl_listing_container.picker .tl_content{background-image:linear-gradient(90deg,transparent calc(100% - 26px),#f0f0f2 26px)}.tl_listing.picker .tl_tree_checkbox,.tl_listing.picker .tl_tree_radio,.tl_listing_container.picker .tl_tree_checkbox,.tl_listing_container.picker .tl_tree_radio{margin-top:2px;margin-left:8px}.tl_listing.picker .tl_tree_checkbox:disabled,.tl_listing.picker .tl_tree_radio:disabled,.tl_listing_container.picker .tl_tree_checkbox:disabled,.tl_listing_container.picker .tl_tree_radio:disabled{visibility:hidden}.tl_listing_container.picker .tl_content p{padding-right:24px}.tl_listing_container.picker .limit_toggler{width:calc(100% - 26px)}.tl_listing tr.odd td{background-color:#fafafc}.tl_listing th,.tl_listing td{padding-left:6px!important;padding-right:6px!important}.list_view .tl_listing img.theme_preview{margin-right:9px}.tl_show{width:96%;margin:18px 2%;padding:9px 0 18px}.tl_show td{padding:4px 6px;line-height:16px;white-space:pre-line;background:#f6f6f8}.tl_show td:first-child{width:34%;white-space:normal}.tl_show td p:last-of-type{margin-bottom:0}.tl_show tr:nth-child(2n) td{background:#fff}.tl_show small{display:block;color:gray}.tl_label{margin-right:12px;font-weight:600;white-space:nowrap}.tl_label small{font-weight:400}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_label small{font-weight:300}}.tl_empty{margin:0;padding:18px}.tl_empty_parent_view{margin:0;padding:18px 0 0}.tl_listing_container+.tl_empty{margin-top:-32px}.tl_noopt{margin:0 0 -1px}.tl_select_trigger{margin-top:-9px;padding:0 6px 3px 0;text-align:right}.tl_radio_reset{margin-top:6px;padding:0 6px 3px 0;text-align:right}.tl_select_label,.tl_radio_label{margin-right:2px;color:#999;font-size:.75rem}.tl_header{padding:6px;background:#f9f9fb;border-top:1px solid #ddd;border-bottom:1px solid #ddd}.tl_header_table{line-height:1.3}.tl_content_header{padding:7px 6px;border-bottom:1px solid #e9e9e9;background:#f6f6f8;font-weight:600}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_content_header{font-weight:500}}.tl_content{padding:6px;border-bottom:1px solid #e9e9e9;overflow:hidden;position:relative;background-color:#fff}.parent_view>ul{background:#f3f3f5}.tl_content.wrapper_stop{border-top:1px solid #e9e9e9}.tl_content.wrapper_start h1{margin-bottom:9px}.tl_content.indent_1{margin-left:20px}.tl_content.indent_2{margin-left:40px}.tl_content.indent_3{margin-left:60px}.tl_content.indent_4{margin-left:80px}.tl_content.indent_5{margin-left:100px}.tl_content.indent_last{border-bottom:0}.tl_content h1,.tl_content h2,.tl_content h3,.tl_content h4,.tl_content h5,.tl_content h6{font-size:.875rem}.tl_content img{max-width:320px;height:auto}.tl_content pre{margin-top:3px;margin-bottom:3px;word-break:break-all;white-space:pre-wrap}.tl_content pre.disabled{color:#a6a6a6}.tl_content .ce_text a{color:#589b0e}.tl_content span.comment{color:#006494;display:inline-block;margin-bottom:3px}.tl_content_left{line-height:16px}.tl_content_right{float:right;text-align:right;margin-left:12px;margin-top:-1px}.tl_right button,.tl_content_right button{margin:0;padding:0;border:0;height:17px;background:0 0}.cte_type{margin:2px 0 6px;font-size:.75rem;color:gray}.cte_type.published,.cte_type.published a{color:#589b0e}.cte_type.unpublished,.cte_type.unpublished a{color:#c33}.limit_height{overflow:hidden;line-height:1.25}.limit_toggler{width:100%;position:absolute;bottom:0;left:0;background:#fff;line-height:11px;text-align:center}.limit_toggler button{margin:0;padding:0;border:0;background:#fff;width:24px;line-height:8px;color:#999;outline:0;border-top-left-radius:2px;border-top-right-radius:2px}.limit_toggler button span{position:relative;top:-4px}.limit_height input[type=file]{position:relative}.limit_height select{-moz-appearance:menulist;-webkit-appearance:menulist}.limit_height label,.limit_height .checkbox_container legend,.limit_height .radio_container legend{display:inline-block;width:180px;vertical-align:top;margin-top:3px}.limit_height .widget{margin-left:0;margin-right:0}.limit_height .widget-submit{margin-left:180px}.limit_height .checkbox_container label,.limit_height .radio_container label{display:initial}.tl_folder_top{padding:5px 0;border-top:1px solid #e3e3e3;border-bottom:1px solid #e3e3e3;background:#f0f0f2}.tl_folder{padding:5px 0;border-bottom:1px solid #e9e9e9;background:#f6f6f8}.tl_folder.tl_folder_dropping,.tl_folder_top.tl_folder_dropping{background-color:#4078a5!important;color:#fff!important}.tl_folder.tl_folder_dropping a,.tl_folder_top.tl_folder_dropping a{color:inherit}.tl_listing .tl_left{flex-grow:1;margin-left:40px;text-indent:-40px;box-sizing:border-box}.tl_listing .tl_left.tl_left_dragging{position:absolute;background:#4078a5;border-radius:10px;color:#fff;padding:5px 10px!important;margin-left:0;text-indent:0;white-space:nowrap}.tl_listing .tl_left.tl_left_dragging .preview-image,.tl_listing .tl_left.tl_left_dragging a img{display:none}.tl_listing .tl_left.tl_left_dragging a,.tl_listing .tl_left.tl_left_dragging .tl_gray{color:inherit}.tl_listing_dragging .hover-div:not(.tl_folder):hover{background-color:transparent!important}.tl_tree_xtnd .tl_file{padding-top:4px;padding-bottom:4px}.tl_tree_xtnd .tl_file .tl_left{margin-left:22px;text-indent:-22px}.tl_tree_xtnd .tl_file .tl_left *{line-height:normal}.tl_tree_xtnd .tl_file .tl_left a{position:relative;top:-1px}.tl_tree_xtnd .tl_file .tl_left img{margin-right:2px}.tl_left>a:last-of-type{vertical-align:middle}.tl_left>a:first-child{vertical-align:bottom}.tl_file_manager .tl_file .tl_left>a:first-child{vertical-align:1px}.tl_file_manager .preview-image{max-width:100px;max-height:75px;width:auto;height:auto;margin:0 0 2px -18px}.tl_file_manager .preview-important{max-width:80px;max-height:60px;width:auto;height:auto;margin:0 0 2px 0;vertical-align:bottom}.tl_listing .tl_right{padding:0 0 1px 9px;white-space:nowrap}.tl_listing,.tl_listing ul{margin:0;padding:0}.tl_listing li{display:flex;margin:0;padding-left:6px;padding-right:6px;list-style-type:none}.tl_listing li.parent{display:inline;padding-left:0;padding-right:0}label.tl_change_selected{margin-right:2px;color:#999;font-size:.75rem}#tl_breadcrumb{margin:0 0 12px;padding:4px 6px;overflow:hidden;background:#fffce1;border:1px solid #d68c23;line-height:24px}#tl_breadcrumb li{margin:0;padding:0 3px;list-style-type:none;float:left}#tl_breadcrumb li a{display:inline-block}#tl_breadcrumb li img{width:16px;height:16px;vertical-align:-3px}.selector_container{margin-top:1px;position:relative}.selector_container ul{margin-bottom:1px;list-style-type:none;overflow:hidden}.selector_container li{margin-right:9px;padding:2px 0}.selector_container p{margin-bottom:1px}.selector_container ul:not(.sgallery) img{margin-right:1px;vertical-align:text-top}ul.sgallery{overflow:hidden}ul.sgallery li{min-width:100px;min-height:75px;float:left;margin:2px 4px 2px 0;padding:0;background:#eee;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.popup #tl_soverview{margin-top:15px}#tl_soverview>div{padding:0 15px 4px;border-bottom:1px solid #e6e6e8}#tl_soverview>div:last-child{border-bottom:0}#tl_soverview table{width:100%;margin-bottom:14px}#tl_messages h2,#tl_shortcuts h2,#tl_versions h2{margin:18px 0 6px}#tl_messages p:not([class]){margin-top:6px}#tl_messages .tl_error,#tl_messages .tl_confirm,#tl_messages .tl_info,#tl_messages .tl_new{padding:3px 6px 3px 21px;background-position:left 4px;background-color:transparent}#tl_shortcuts p a{text-decoration:underline}#tl_versions{margin-bottom:0}#tl_versions th{background:#f6f6f8;padding:6px;border-top:1px solid #e9e9e9}#tl_versions th,#tl_versions td{border-bottom:1px solid #e9e9e9}#tl_versions td{padding:4px}#tl_versions td:first-child{white-space:nowrap}#tl_versions td:last-child{width:32px;white-space:nowrap;text-align:right}#tl_versions img.undo{padding-right:2px}#tl_versions .pagination{margin-top:18px;margin-bottom:14px}.tl_chmod{width:100%}.tl_chmod th{height:18px;text-align:center;font-weight:400;background:#f0f0f2}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_chmod th{font-weight:300}}.tl_chmod td{text-align:center;background:#f6f6f8}.tl_chmod th,.tl_chmod td{width:14.2857%;padding:6px;border:1px solid #fff}.tl_modulewizard button,.tl_optionwizard button,.tl_key_value_wizard button,.tl_tablewizard button,.tl_listwizard button,.tl_checkbox_wizard button,.tl_metawizard button,.tl_sectionwizard button{margin:0;padding:0;border:0;background:0 0}.tl_modulewizard{width:100%;max-width:800px;margin-top:2px}.tl_modulewizard td{position:relative;padding:0 3px 0 0}.tl_modulewizard th{font-size:.75rem;font-weight:400;padding:0 6px 1px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_modulewizard th{font-weight:300}}.tl_modulewizard td:last-child{width:1%;white-space:nowrap}.tl_modulewizard img{position:relative;top:1px}.js .tl_modulewizard input.mw_enable{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tl_modulewizard img.mw_enable{display:none}.js .tl_modulewizard img.mw_enable{display:inline;margin-right:1px}.tl_optionwizard{width:100%;max-width:600px}.tl_key_value_wizard{width:100%;max-width:450px}.tl_optionwizard,.tl_key_value_wizard{margin-top:2px}.tl_optionwizard label,.tl_key_value_wizard label{margin-right:3px}.tl_optionwizard td,.tl_key_value_wizard td{padding:0 3px 0 0}.tl_optionwizard th,.tl_key_value_wizard th{font-size:.75rem;font-weight:400;padding:0 6px 1px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_optionwizard th,.tl_key_value_wizard th{font-weight:300}}.tl_optionwizard td:nth-child(n+3),.tl_key_value_wizard td:nth-child(n+3){width:1%;white-space:nowrap}.tl_optionwizard img,.tl_key_value_wizard img{position:relative;top:1px}.tl_optionwizard .fw_checkbox,.tl_key_value_wizard .fw_checkbox{margin:0 1px}#tl_tablewizard{margin-top:2px;padding-bottom:2px;overflow:auto}.tl_tablewizard td{padding:0 3px 0 0}.tl_tablewizard thead td{padding-bottom:3px;text-align:center;white-space:nowrap}.tl_tablewizard tbody td:last-child{white-space:nowrap}.tl_tablewizard td.tcontainer{vertical-align:top}.tl_listwizard .tl_text{width:78%}.tl_checkbox_wizard .fixed{display:block;margin-top:1px}.tl_checkbox_wizard .sortable span{display:block}.tl_checkbox_wizard .sortable img{vertical-align:bottom}.tl_metawizard{margin:3px 0 6px}.tl_metawizard li{overflow:hidden;margin-bottom:2px;padding:9px;background:#f3f3f5}.tl_metawizard li.odd{background:#f9f9fb}.tl_metawizard span img{cursor:pointer}.tl_metawizard label{float:left;width:18%;margin-top:9px}.tl_metawizard .tl_text{float:left;width:82%;margin:1px 0}.tl_metawizard .tl_text+a{top:6px}.tl_metawizard br{clear:left}.tl_metawizard .lang{display:block;margin-bottom:9px;font-weight:600;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_metawizard .lang{font-weight:500}}.tl_metawizard_img{position:absolute;right:0;top:-1px}.tl_metawizard_new .tl_select{margin-right:4px;max-width:200px}.tl_metawizard_new .tl_submit{padding-top:6px;padding-bottom:6px}.tl_sectionwizard{margin-top:2px;width:100%;max-width:680px}.tl_sectionwizard td{width:25%;position:relative;padding:0 3px 0 0}.tl_sectionwizard th{font-size:.75rem;font-weight:400;padding:0 4px 1px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_sectionwizard th{font-weight:300}}.tl_sectionwizard td:last-child{white-space:nowrap}#paste_hint{position:relative}.tl_message+#paste_hint{margin-top:-12px}#paste_hint p{position:absolute;font-family:"Architects Daughter",cursive;font-size:1rem;color:#838990;top:0;right:30px;padding:0 36px 24px 0;background:url(icons/arrow_right.svg) bottom right no-repeat;transform:rotate(-1deg)}.sort_hint{position:absolute;font-family:"Architects Daughter",cursive;font-size:1rem;color:#838990;top:-50px;left:160px;padding:0 6px 24px 42px;background:url(icons/arrow_left.svg) 6px bottom no-repeat;transform:rotate(-2deg)}.widget+.subpal .sort_hint{left:260px}.widget+.widget .sort_hint{left:320px}.serp{margin-top:1px}.serp-preview{max-width:600px;margin:1px 0 2px;padding:4px 6px;font-family:Arial,sans-serif;font-weight:400;border:1px dotted #aaa;border-radius:2px}.serp-preview p{margin-bottom:0;line-height:1.3}.serp-preview .title{font-size:18px;color:#1a0dab}.serp-preview .url{color:#006621}.serp-preview .description{margin-top:2px;color:#545454}#tl_ajaxBox{width:20%;padding:2em;position:absolute;left:40%;background:#fff url(icons/loading.svg) no-repeat right 2em center;border:2px solid #111;border-radius:2px;font-size:1rem;text-align:left}#tl_ajaxOverlay{width:100%;height:100%;position:absolute;top:0;left:0;background:#fff;opacity:.5}.ce_gallery ul{overflow:hidden}.ce_gallery li{float:left;margin:0 6px 6px 0}.drag-handle{cursor:move}ul.sortable li{cursor:move;position:relative}ul.sortable li .dirname{display:none}ul.sortable li:hover .dirname{display:inline}ul.sortable button{position:absolute;top:0;right:0;border:0;background:#eee;margin:0;padding:0 0 3px;font-size:22px;line-height:9px;cursor:pointer;transition:all .1s linear}ul.sortable button:hover{background:#f9f9f9}ul.sortable button[disabled]{color:#999;cursor:not-allowed}ul.sortable button[disabled]:hover{background:rgba(255,255,255,.7)}#picker-menu{padding:9px 6px 0;border-bottom:1px solid #ddd}#picker-menu li{display:inline-block;padding:8px 0;background-color:#f9f9fb;border:1px solid #ddd;border-radius:2px 2px 0 0;position:relative;top:1px}#picker-menu li:hover{background-color:#f3f3f5}#picker-menu li.current{background-color:#f3f3f5;border-bottom-color:#f3f3f5}#picker-menu a{padding:3px 12px 3px 32px;background:url(icons/manager.svg) 12px center no-repeat}#picker-menu a:hover{color:#444}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#picker-menu a:hover{color:#222}}#picker-menu a.pagePicker{background-image:url(icons/pagemounts.svg);background-size:16px}#picker-menu a.filePicker{background-image:url(icons/filemounts.svg);background-size:14px}#picker-menu a.articlePicker{background-image:url(icons/articles.svg);background-size:16px}#picker-menu a.close{background-image:url(icons/back.svg)}.ace_editor{padding:3px}.ace_editor,.ace_editor *{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important;font-size:.75rem!important;color:#444}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.ace_editor,.ace_editor *{color:#222}}.ace-fullsize{overflow:hidden!important}.ace-fullsize .ace_editor{position:fixed!important;top:0;right:0;bottom:0;left:0;width:auto!important;height:auto!important;margin:0;border:0;z-index:10000}div.mce-edit-area{width:99.9%}time[title]{cursor:help}.float_left{float:left}.float_right{float:right}#manager{padding:9px 6px 0;border-bottom:1px solid #ddd}#manager a{padding:3px 12px 3px 32px;background:url(icons/manager.svg) 12px center no-repeat}.header_icon,.header_clipboard,.header_back,.header_new,.header_rss,.header_edit_all,.header_delete_all,.header_new_folder,.header_css_import,.header_theme_import,.header_store,.header_toggle,.header_sync{padding:3px 0 3px 21px;background-position:left center;background-repeat:no-repeat;margin-left:15px}.list_icon{margin-left:-3px;padding-left:20px;background-position:left center;background-repeat:no-repeat}.list_icon_new{width:16px;background-position:1px center;background-repeat:no-repeat}.header_clipboard{background-image:url(icons/clipboard.svg)}.header_back{background-image:url(icons/back.svg)}.header_new{background-image:url(icons/new.svg)}.header_rss{background-image:url(icons/rss.svg)}.header_edit_all{background-image:url(icons/all.svg)}.header_delete_all{background-image:url(icons/deleteAll.svg)}.header_new_folder{padding-left:24px;background-image:url(icons/newfolder.svg)}.header_css_import{background-image:url(icons/cssimport.svg)}.header_theme_import{background-image:url(icons/theme_import.svg)}.header_store{padding-left:18px;background-image:url(icons/store.svg)}.header_toggle{background-image:url(icons/folPlus.svg)}.header_sync{background-image:url(icons/sync.svg)}.tl_text_trbl,.tl_imageSize_0,.tl_imageSize_1,#ctrl_playerSize input{background:url(icons/hints.svg) no-repeat right 1px top 2px}#ctrl_playerSize_1,.tl_imageSize_1{background-position:right 1px top -28px!important}.trbl_top{background-position:right 1px top -59px!important}.trbl_right{background-position:right 1px top -89px!important}.trbl_bottom{background-position:right 1px top -119px!important}.trbl_left{background-position:right 1px top -149px!important}#ctrl_shadowsize_top{background-position:right 1px top -179px!important}#ctrl_shadowsize_right{background-position:right 1px top -209px!important}#ctrl_shadowsize_bottom{background-position:right 1px top -238px!important}#ctrl_shadowsize_left{background-position:right 1px top -269px!important}#ctrl_borderradius_top{background-position:left -299px!important}#ctrl_borderradius_right{background-position:right 1px top -329px!important}#ctrl_borderradius_bottom{background-position:right 1px top -352px!important}#ctrl_borderradius_left{background-position:left -382px!important}label.error,legend.error,.tl_checkbox_container.error legend{color:#c33}.tl_tbox .tl_error,.tl_box .tl_error{background:0 0;padding:0;margin-bottom:0;font-size:.75rem}.tl_formbody_edit>.tl_error{margin-top:9px}.broken-image{display:inline-block;padding:12px 12px 12px 30px;background:#faebeb url(icons/error.svg) no-repeat 9px center;color:#c33;text-indent:0}fieldset.tl_tbox,fieldset.tl_box{padding-top:9px;border-top:26px solid #f6f6f6;border-left:0;border-right:0}fieldset.tl_tbox.nolegend,fieldset.tl_box.nolegend{border-top:0}fieldset.tl_tbox>legend,fieldset.tl_box>legend{width:100%;box-sizing:border-box;color:#6a6a6c;padding:14px 0 0 28px;background:url(icons/navcol.svg) 13px 16px no-repeat;cursor:pointer}fieldset.collapsed{margin-bottom:0;padding-top:14px;padding-bottom:0}fieldset.collapsed div{display:none!important}fieldset.collapsed>legend{background:url(icons/navexp.svg) 13px 16px no-repeat}#tl_maintenance_cache table{width:100%}#tl_maintenance_cache th,#tl_maintenance_cache td{border-bottom:1px solid #e9e9e9}#tl_maintenance_cache th{background:#f6f6f8;padding:6px;border-top:1px solid #e9e9e9}#tl_maintenance_cache td{padding:6px;line-height:1.2}#tl_maintenance_cache tr:nth-child(even) td{background:#fcfcfe}#tl_maintenance_cache td span{color:#999}#tl_maintenance_cache td:first-child{width:16px}.mac #tl_maintenance_cache td:first-child .tl_checkbox{top:-2px}#tl_maintenance_cache .nw{white-space:nowrap}#tl_maintenance_cache .tl_checkbox_container{margin-top:12px}#tl_maintenance_cache .tl_checkbox_container label{font-weight:600}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tl_maintenance_cache .tl_checkbox_container label{font-weight:500}}.pagination{overflow:hidden;background:#f6f6f8;margin-bottom:18px;border:solid #e9e9e9;border-width:1px 0;padding:12px 15px}.pagination ul{width:60%;float:right;text-align:right;padding-right:3px}.pagination p{width:30%;float:left;margin-bottom:0}.pagination li{display:inline;padding-right:3px}.pagination .active{color:#999}.pagination-lp{margin-left:15px;margin-right:15px}#sync-results{overflow:hidden;margin:18px 15px 0}#sync-results p{margin-bottom:0}#sync-results .left{float:left;padding:2px 0}#sync-results .right{float:right}#result-list{margin:15px}#result-list .tl_error,#result-list .tl_confirm,#result-list .tl_info,#result-list .tl_new{padding:3px 0;background:0 0}.dropzone{margin:2px 0;min-height:auto!important;border:3px dashed #ddd!important;border-radius:2px}.dropzone-filetree{display:none;position:absolute;top:0;left:0;width:100%;height:100%;opacity:.8;z-index:1}.dropzone-filetree-enabled{display:block}.dz-message span{font-size:1.3125rem;color:#ccc}@media (max-width:991px){body{background:#eaeaec}#header{width:100%;padding:0;position:fixed;top:0;z-index:2;transition:transform .2s ease;-webkit-transform:none;transform:none;will-change:transform}#container{display:block;padding-top:40px}#main,#left{float:none;overflow:hidden}#main{width:100%!important;position:relative;transition:transform .2s ease;-webkit-transform:none;transform:none;will-change:transform}.show-navigation #main{-webkit-transform:translateX(240px);transform:translateX(240px)}#left{position:absolute;top:40px;width:240px;transition:transform .2s ease;-webkit-transform:translateX(-240px);transform:translateX(-240px);will-change:transform}.show-navigation #left{-webkit-transform:none;transform:none}#tmenu .burger{display:inline}}@media (max-width:767px){#header.down{-webkit-transform:translateY(-40px);transform:translateY(-40px)}#header h1 a{width:22px;padding:12px;text-indent:34px;overflow:hidden}#tmenu>li>a{width:16px;margin-bottom:-2px;position:relative;overflow:hidden;white-space:nowrap;text-indent:28px;background-size:18px!important}#tmenu sup{top:6px;font-size:.5rem}#tmenu .icon-debug{background:url(icons/debug.svg) center center no-repeat}#tmenu .icon-preview{background:url(icons/preview.svg) center center no-repeat}#tmenu h2{width:16px;margin:0 0 -2px;padding-right:12px;overflow:hidden;white-space:nowrap;text-indent:28px;background:url(icons/profile.svg) center center no-repeat;background-size:18px}#main .content{margin:15px 10px}#main_headline{margin:15px 0;padding:0 11px}div.tl_tbox,div.tl_box{position:relative}.tl_content_left{width:100%;float:none}.showColumns th,.showColumns td{display:block}.showColumns th:empty{display:none}.tl_label{white-space:normal}.list_view .tl_listing img.theme_preview{display:none}.tl_filter{box-sizing:border-box;padding:0 3px 0 7px}.tl_filter strong{display:none}.tl_filter .tl_select{display:block;max-width:100%}.tl_search{width:76%;max-width:283px}.tl_search .tl_select{width:36%}.tl_search .tl_text{width:26%}.tl_sorting{width:60%;max-width:212px}.tl_limit{width:50%;max-width:177px}.tl_submit_panel{float:right;z-index:1}input.tl_submit{margin-top:3px;margin-bottom:3px;padding-left:6px!important;padding-right:7px!important}.tl_listing .tl_left,.tl_show td{word-break:break-word}#tl_breadcrumb li{padding:3px}#tl_versions{display:none}.tl_version_panel .tl_select{width:44%}.tl_modulewizard td:first-child{width:1%}.tl_modulewizard td:first-child .tl_select{max-width:52vw}#paste_hint,.sort_hint{display:none}#tl_maintenance_cache table{width:100%}#tl_maintenance_cache tr th:last-child,#tl_maintenance_cache tr td:last-child{display:none}.tl_file_list .ellipsis{padding-right:10px}}@media (max-width:599px){.tl_metawizard label{width:auto;float:none;font-size:.9em;display:block;margin-top:3px}.tl_metawizard .tl_text{width:100%}}@media (max-width:479px){.tl_modulewizard td:first-child .tl_select{max-width:48vw}} \ No newline at end of file +body{background:#cfcfd3;overflow-y:scroll}body.popup{background:#fff}#header{min-height:40px;text-align:left}#header .inner{background:#f47c00}body:not(.fullscreen) #header .inner{max-width:1440px;margin:0 auto}#header,#header a{color:#fff}#header h1{position:absolute}#header h1 a{display:block;padding:12px 12px 12px 43px;background:url(icons/logo.svg) no-repeat 10px center;font-weight:400}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#header h1 a{font-weight:300}}#tmenu{display:flex;justify-content:flex-end}#tmenu li{position:relative}#tmenu a,#tmenu h2{padding:13px 12px;display:inline-block}#tmenu img{vertical-align:top}#tmenu sup{position:absolute;top:5px;left:20px;z-index:1;font-size:.6rem;background:#fff;padding:2px;border-radius:2px;text-indent:0;color:#f47c00;font-weight:400}#tmenu .burger{display:none}#tmenu .burger button{margin-right:-2px;padding:8px 10px 9px;background:0 0;border:0;vertical-align:top}#tmenu .burger img{margin-bottom:-1px}#tmenu h2{padding-right:26px;cursor:pointer;background:url(icons/chevron-down.svg) right 9px top 14px no-repeat;font-size:.875rem;font-weight:400;color:#fff}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tmenu h2{font-weight:300}}#tmenu a,#tmenu h2,#tmenu .burger button{transition:background-color .3s ease}#tmenu a:hover,#tmenu a.hover,#tmenu li:hover h2,#tmenu .active h2,#tmenu .burger button:hover{background-color:#e87600}#tmenu ul.level_2{min-width:150px;position:absolute;right:6px;margin-top:5px;padding:6px 0 9px;background:#fff;box-shadow:0 0 3px #999;z-index:1;color:#444;text-align:left;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease}#tmenu .active ul.level_2{opacity:1;visibility:visible}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tmenu ul.level_2{color:#222}}#tmenu ul.level_2 li a{display:block;color:inherit;padding:6px 20px 6px 40px;white-space:nowrap}#tmenu ul.level_2 li a:hover{background-color:#eee}#tmenu ul.level_2 .info{color:gray;padding:9px 20px 15px;border-bottom:1px solid #e6e6e8;line-height:1.4;margin-bottom:9px;white-space:nowrap}#tmenu ul.level_2 strong{color:#222;display:block}#tmenu ul.level_2:before{content:"";display:block;width:0;height:0;position:absolute;right:9px;top:-14px;border:7px solid transparent;border-bottom-color:#fff}#tmenu ul.level_2:after{content:"";display:block;width:100%;height:5px;position:absolute;top:-5px}#tmenu .icon-alert{width:16px;margin-bottom:-2px;position:relative;background:url(icons/alert.svg) center center no-repeat;overflow:hidden;white-space:nowrap;text-indent:28px}#tmenu .icon-profile{background:url(icons/profile_dark.svg) 20px center no-repeat}#tmenu .icon-security{background:url(icons/shield_dark.svg) 20px center no-repeat}#tmenu .icon-logout{background:url(icons/exit_dark.svg) 20px center no-repeat}#container{display:flex;min-height:calc(100vh - 40px);background:#cfcfd3}body:not(.fullscreen) #container{max-width:1440px;margin:0 auto}.popup #container{padding:0;width:auto;min-height:0;background:#fff;max-width:none}#left{float:left;width:225px;min-height:calc(100vh - 40px);background:#0f1c26;display:flex;flex-direction:column}#left .version{margin-top:4em;padding:15px;border-top:1px solid #3a454d;font-size:.75rem;line-height:1.4;background:#172b3b}#left .version,#left .version a{color:#9fa4a8}#main{float:left;width:calc(100% - 225px);min-height:calc(100vh - 40px);background:#eaeaec}.popup #main{float:none;width:auto;max-width:none;min-height:0;margin:0;padding:0;border:0;display:initial}#main .content{margin:15px;background:#fff;border:1px solid #d0d0d2}.popup #main .content{margin:0;border:0}#tl_navigation{flex-grow:1}#tl_navigation .tl_level_1_group{margin:0 15px;padding:15px 0 6px;border-top:1px solid #3a454d}#tl_navigation .tl_level_1_group:first-child{border-top:0;padding-top:18px}#tl_navigation .tl_level_1_group a{display:block;padding:3px 3px 3px 24px;color:#9fa4a8;font-size:.75rem;text-transform:uppercase}#tl_navigation .group-content{background:url(icons/content.svg) 3px 2px no-repeat}#tl_navigation .group-design{background:url(icons/monitor.svg) 3px 2px no-repeat}#tl_navigation .group-accounts{background:url(icons/person.svg) 3px 2px no-repeat}#tl_navigation .group-system{background:url(icons/wrench.svg) 3px 2px no-repeat}#tl_navigation .node-collapsed{padding-bottom:14px}#tl_navigation .tl_level_2{padding:0 0 15px}#tl_navigation .tl_level_2 li{border-left:4px solid #0f1c26}#tl_navigation .tl_level_2 li.active{background-color:#172b3b;border-left-color:#f47c00}#tl_navigation .tl_level_2 a{display:block;padding:6px 18px 6px 35px;font-weight:400;color:#d3d5d7;transition:color .2s ease}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tl_navigation .tl_level_2 a{font-weight:300}}#tl_navigation .tl_level_2 li:hover a{color:#fff}#tl_buttons{margin:0;padding:12px 15px;text-align:right}.toggleWrap{cursor:pointer}.opacity{-moz-opacity:.8;opacity:.8}#main_headline{margin:20px 0;padding:0 16px;font-size:1.1rem}.popup #main_headline{display:none}#main_headline span:nth-child(even){font-weight:400}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#main_headline span:nth-child(even){font-weight:300}}h2.sub_headline{margin:3px 18px;padding:7px 0}.tl_gerror{margin:12px;padding:3px 0 3px 22px;background:url(icons/error.svg) no-repeat left center}.tl_error,.tl_confirm,.tl_info,.tl_new{margin:0 0 1px;padding:11px 18px 11px 37px;line-height:1.3}.tl_error{background:#faebeb url(icons/error.svg) no-repeat 16px 12px}.tl_confirm{background:#eefcde url(icons/ok.svg) no-repeat 16px 12px}.tl_info{background:#e9f0f7 url(icons/show.svg) no-repeat 16px 12px}.tl_new{background:#fbf2e5 url(icons/featured.svg) no-repeat 16px 12px}.tl_gerror,.tl_gerror a,.tl_error,.tl_error a{color:#c33}.tl_confirm,.tl_confirm a{color:#589b0e}.tl_info,.tl_info a{color:#006494}.tl_new,.tl_new a{color:#d68c23}.tl_panel,.tl_version_panel{padding:8px 10px 8px 0;background:#f3f3f5;border-bottom:1px solid #ddd;text-align:right}.tl_version_panel .tl_select{max-width:280px}.tl_version_panel .tl_formbody{position:relative}.tl_img_submit{width:16px;height:16px;border:0;margin:0;padding:0;text-indent:16px;white-space:nowrap;overflow:hidden;position:relative;top:9px;vertical-align:top;cursor:pointer}.filter_apply{background:url(icons/filter-apply.svg) center center no-repeat}.filter_reset{background:url(icons/filter-reset.svg) center center no-repeat}.tl_subpanel{float:right;letter-spacing:-.31em}.tl_subpanel *{letter-spacing:normal}.tl_subpanel strong,.tl_search span{vertical-align:middle}.tl_submit_panel{min-width:32px;padding-left:6px;padding-right:3px}.tl_panel .active,.tl_panel_bottom .active,#search .active{background-color:#fffce1}.tl_filter{width:100%}.tl_filter .tl_select{max-width:14.65%;margin-left:3px}.tl_submit_panel+.tl_filter{width:86%}.tl_limit{width:22%}.tl_limit .tl_select{width:52%;margin-left:3px}.tl_search{width:40%}.tl_search .tl_select{width:38%;margin-left:3px;margin-right:1%}.tl_search .tl_text{width:30%;margin-left:1%;-webkit-appearance:textfield;box-sizing:content-box}.tl_sorting{width:26%}.tl_sorting .tl_select{width:60%;margin-left:1%}input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.tl_xpl{padding:0 18px}.tl_tbox,.tl_box{padding:12px 0 26px;border-bottom:1px solid #e6e6e8}.tl_tbox:last-child,.tl_box:last-child{border-bottom:0}.tl_box h3,.tl_tbox h3,.tl_xpl h3{margin:0;padding:14px 0 1px;font-size:.875rem}.tl_box h4,.tl_tbox h4{margin:6px 0 0;padding:0;font-size:.875rem}.tl_tbox.theme_import{padding-left:15px;padding-right:15px}.tl_tbox.theme_import h3,.tl_tbox.theme_import h4,.tl_tbox.theme_import p{line-height:1.3}.tl_help,.tl_help *{font-size:.75rem}.tl_help,.tl_help a{margin-bottom:0;line-height:1.25;color:gray}.tl_help a:hover,.tl_help a:focus,.tl_help a:active{text-decoration:underline}.tl_formbody_edit.nogrid .w50{float:none}.tl_formbody_edit.nogrid .m12{margin-top:0;margin-bottom:0}.tl_edit_form .tl_formbody_edit{border-top:1px solid #e6e6e8}.tl_formbody_submit{border-top:1px solid #ddd}.tl_submit_container{padding:8px 15px;background:#f3f3f5}.tl_submit_container .tl_submit{margin-top:2px;margin-bottom:2px}.maintenance_active{padding-top:12px}.maintenance_active,.maintenance_inactive{border-top:1px solid #e6e6e8}.maintenance_inactive:last-child{padding-bottom:9px}.maintenance_inactive .tl_tbox{border:0!important;padding:6px 15px 14px}.maintenance_inactive .tl_message{margin-top:0}.maintenance_inactive h2.sub_headline{margin:18px 15px 3px}.maintenance_inactive .tl_submit_container{background:0 0;padding:0 15px 24px;border:0}.maintenance_inactive:last-of-type .tl_submit_container{padding-bottom:10px}#tl_maintenance_mode .tl_message{margin-bottom:12px}#tl_maintenance_mode .tl_message>p{padding-top:0;padding-bottom:0;background-color:transparent;background-position-y:center}#tl_maintenance_index .tl_tbox{margin-top:-12px}.two-factor{border-top:1px solid #e6e6e8;padding-bottom:9px}.two-factor h2.sub_headline{margin:18px 15px 3px}.two-factor>p{margin:0 15px 12px;line-height:1.3}.two-factor li{margin-left:2em;list-style:initial}.two-factor .qr-code{margin:0 15px}.two-factor .widget{height:auto;margin:15px 15px 12px}.two-factor .widget .tl_error{margin:0;padding:1px 0;background:0 0;font-size:.75rem;line-height:1.25}.two-factor .tl_submit_container{background:0 0;padding:0 15px 10px;border:0}.two-factor .submit_container{clear:both;margin:0 15px 12px}.two-factor .tl_message{margin-bottom:12px}.two-factor .tl_message>p{padding-top:0;padding-bottom:0;background-color:transparent;background-position-y:center}#search{margin:18px 18px -9px;text-align:right}#search .tl_text{max-width:160px;-webkit-appearance:textfield;box-sizing:content-box}.tl_edit_preview{margin-top:18px}.tl_edit_preview img{max-width:100%;height:auto;padding:2px;border:1px solid #ddd;background:#fff}.tl_edit_preview_enabled{position:relative;cursor:crosshair;display:inline-block}.tl_edit_preview_important_part{position:absolute;margin:-1px;border:1px solid #000;box-shadow:0 0 0 1px #fff,inset 0 0 0 1px #fff;opacity:.5}#tl_rebuild_index{padding:0 18px 18px;line-height:1.3}#index_note{margin:24px 0 18px;padding:11px 12px 12px;background:#ffc;border:1px solid #f90;font-size:.875rem}#index_loading{margin:0;padding:12px 12px 12px 24px;background:url(icons/loading.svg) no-repeat left center;background-size:16px;color:#006494}#index_complete{margin:0;padding:12px 12px 12px 24px;background:url(icons/ok.svg) no-repeat left center;color:#589b0e}table.tl_listing{width:100%}.tl_listing_container{padding:2px 0;margin:20px 15px 16px}.tl_listing_container.tree_view{position:relative}#tl_buttons+.tl_listing_container{margin-top:10px}#paste_hint+.tl_listing_container{margin-top:30px}.tl_folder_list,.tl_folder_tlist{padding:7px 0;border-bottom:1px solid #e9e9e9;background:#f3f3f5;font-weight:600}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_folder_list,.tl_folder_tlist{font-weight:500}}.tl_folder_tlist{border-top:1px solid #e9e9e9}.tl_file,.tl_file_list{padding:5px 0;border-bottom:1px solid #e9e9e9;background:#fff}.tl_file_list{padding:7px 0}.tl_file_list .ellipsis{height:15px;text-overflow:ellipsis;overflow:hidden;padding-right:18px;word-break:break-all}.tl_right_nowrap{padding:3px 0;text-align:right;white-space:nowrap}.tl_listing.picker .tl_file,.tl_listing.picker .tl_folder,.tl_listing.picker .tl_right_nowrap,.tl_listing_container.picker .tl_content_header,.tl_listing_container.picker .tl_content{background-image:linear-gradient(90deg,transparent calc(100% - 26px),#f0f0f2 26px)}.tl_listing.picker .tl_tree_checkbox,.tl_listing.picker .tl_tree_radio,.tl_listing_container.picker .tl_tree_checkbox,.tl_listing_container.picker .tl_tree_radio{margin-top:2px;margin-left:8px}.tl_listing.picker .tl_tree_checkbox:disabled,.tl_listing.picker .tl_tree_radio:disabled,.tl_listing_container.picker .tl_tree_checkbox:disabled,.tl_listing_container.picker .tl_tree_radio:disabled{visibility:hidden}.tl_listing_container.picker .tl_content p{padding-right:24px}.tl_listing_container.picker .limit_toggler{width:calc(100% - 26px)}.tl_listing tr.odd td{background-color:#fafafc}.tl_listing th,.tl_listing td{padding-left:6px!important;padding-right:6px!important}.list_view .tl_listing img.theme_preview{margin-right:9px}.tl_show{width:96%;margin:18px 2%;padding:9px 0 18px}.tl_show td{padding:4px 6px;line-height:16px;white-space:pre-line;background:#f6f6f8}.tl_show td:first-child{width:34%;white-space:normal}.tl_show td p:last-of-type{margin-bottom:0}.tl_show tr:nth-child(2n) td{background:#fff}.tl_show small{display:block;color:gray}.tl_label{margin-right:12px;font-weight:600;white-space:nowrap}.tl_label small{font-weight:400}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_label small{font-weight:300}}.tl_empty{margin:0;padding:18px}.tl_empty_parent_view{margin:0;padding:18px 0 0}.tl_listing_container+.tl_empty{margin-top:-32px}.tl_noopt{margin:0 0 -1px}.tl_select_trigger{margin-top:-9px;padding:0 6px 3px 0;text-align:right}.tl_radio_reset{margin-top:6px;padding:0 6px 3px 0;text-align:right}.tl_select_label,.tl_radio_label{margin-right:2px;color:#999;font-size:.75rem}.tl_header{padding:6px;background:#f9f9fb;border-top:1px solid #ddd;border-bottom:1px solid #ddd}.tl_header_table{line-height:1.3}.tl_content_header{padding:7px 6px;border-bottom:1px solid #e9e9e9;background:#f6f6f8;font-weight:600}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_content_header{font-weight:500}}.tl_content{padding:6px;border-bottom:1px solid #e9e9e9;overflow:hidden;position:relative;background-color:#fff}.parent_view>ul{background:#f3f3f5}.tl_content.wrapper_stop{border-top:1px solid #e9e9e9}.tl_content.wrapper_start h1{margin-bottom:9px}.tl_content.indent_1{margin-left:20px}.tl_content.indent_2{margin-left:40px}.tl_content.indent_3{margin-left:60px}.tl_content.indent_4{margin-left:80px}.tl_content.indent_5{margin-left:100px}.tl_content.indent_last{border-bottom:0}.tl_content h1,.tl_content h2,.tl_content h3,.tl_content h4,.tl_content h5,.tl_content h6{font-size:.875rem}.tl_content img{max-width:320px;height:auto}.tl_content pre{margin-top:3px;margin-bottom:3px;word-break:break-all;white-space:pre-wrap}.tl_content pre.disabled{color:#a6a6a6}.tl_content .ce_text a{color:#589b0e}.tl_content span.comment{color:#006494;display:inline-block;margin-bottom:3px}.tl_content_left{line-height:16px}.tl_content_right{float:right;text-align:right;margin-left:12px;margin-top:-1px}.tl_right button,.tl_content_right button{margin:0;padding:0;border:0;height:17px;background:0 0}.cte_type{margin:2px 0 6px;font-size:.75rem;color:gray}.cte_type.published,.cte_type.published a{color:#589b0e}.cte_type.unpublished,.cte_type.unpublished a{color:#c33}.limit_height{overflow:hidden;line-height:1.25}.limit_toggler{width:100%;position:absolute;bottom:0;left:0;background:#fff;line-height:11px;text-align:center}.limit_toggler button{margin:0;padding:0;border:0;background:#fff;width:24px;line-height:8px;color:#999;outline:0;border-top-left-radius:2px;border-top-right-radius:2px}.limit_toggler button span{position:relative;top:-4px}.limit_height input[type=file]{position:relative}.limit_height select{-moz-appearance:menulist;-webkit-appearance:menulist}.limit_height label,.limit_height .checkbox_container legend,.limit_height .radio_container legend{display:inline-block;width:180px;vertical-align:top;margin-top:3px}.limit_height .widget{margin-left:0;margin-right:0}.limit_height .widget-submit{margin-left:180px}.limit_height .checkbox_container label,.limit_height .radio_container label{display:initial}.tl_folder_top{padding:5px 0;border-top:1px solid #e3e3e3;border-bottom:1px solid #e3e3e3;background:#f0f0f2}.tl_folder{padding:5px 0;border-bottom:1px solid #e9e9e9;background:#f6f6f8}.tl_folder.tl_folder_dropping,.tl_folder_top.tl_folder_dropping{background-color:#4078a5!important;color:#fff!important}.tl_folder.tl_folder_dropping a,.tl_folder_top.tl_folder_dropping a{color:inherit}.tl_listing .tl_left{flex-grow:1;margin-left:40px;text-indent:-40px;box-sizing:border-box}.tl_listing .tl_left.tl_left_dragging{position:absolute;background:#4078a5;border-radius:10px;color:#fff;padding:5px 10px!important;margin-left:0;text-indent:0;white-space:nowrap}.tl_listing .tl_left.tl_left_dragging .preview-image,.tl_listing .tl_left.tl_left_dragging a img{display:none}.tl_listing .tl_left.tl_left_dragging a,.tl_listing .tl_left.tl_left_dragging .tl_gray{color:inherit}.tl_listing_dragging .hover-div:not(.tl_folder):hover{background-color:transparent!important}.tl_tree_xtnd .tl_file{padding-top:4px;padding-bottom:4px}.tl_tree_xtnd .tl_file .tl_left{margin-left:22px;text-indent:-22px}.tl_tree_xtnd .tl_file .tl_left *{line-height:normal}.tl_tree_xtnd .tl_file .tl_left a{position:relative;top:-1px}.tl_tree_xtnd .tl_file .tl_left img{margin-right:2px}.tl_left>a:last-of-type{vertical-align:middle}.tl_left>a:first-child{vertical-align:bottom}.tl_file_manager .tl_file .tl_left>a:first-child{vertical-align:1px}.tl_file_manager .preview-image{max-width:100px;max-height:75px;width:auto;height:auto;margin:0 0 2px -18px}.tl_file_manager .preview-important{max-width:80px;max-height:60px;width:auto;height:auto;margin:0 0 2px 0;vertical-align:bottom}.tl_listing .tl_right{padding:0 0 1px 9px;white-space:nowrap}.tl_listing,.tl_listing ul{margin:0;padding:0}.tl_listing li{display:flex;margin:0;padding-left:6px;padding-right:6px;list-style-type:none}.tl_listing li.parent{display:inline;padding-left:0;padding-right:0}label.tl_change_selected{margin-right:2px;color:#999;font-size:.75rem}#tl_breadcrumb{margin:0 0 12px;padding:4px 6px;overflow:hidden;background:#fffce1;border:1px solid #d68c23;line-height:24px}#tl_breadcrumb li{margin:0;padding:0 3px;list-style-type:none;float:left}#tl_breadcrumb li a{display:inline-block}#tl_breadcrumb li img{width:16px;height:16px;vertical-align:-3px}.selector_container{margin-top:1px;position:relative}.selector_container ul{margin-bottom:1px;list-style-type:none;overflow:hidden}.selector_container li{margin-right:9px;padding:2px 0}.selector_container p{margin-bottom:1px}.selector_container ul:not(.sgallery) img{margin-right:1px;vertical-align:text-top}ul.sgallery{overflow:hidden}ul.sgallery li{min-width:100px;min-height:75px;float:left;margin:2px 4px 2px 0;padding:0;background:#eee;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.popup #tl_soverview{margin-top:15px}#tl_soverview>div{padding:0 15px 4px;border-bottom:1px solid #e6e6e8}#tl_soverview>div:last-child{border-bottom:0}#tl_soverview table{width:100%;margin-bottom:14px}#tl_messages h2,#tl_shortcuts h2,#tl_versions h2{margin:18px 0 6px}#tl_messages p:not([class]){margin-top:6px}#tl_messages .tl_error,#tl_messages .tl_confirm,#tl_messages .tl_info,#tl_messages .tl_new{padding:3px 6px 3px 21px;background-position:left 4px;background-color:transparent}#tl_shortcuts p a{text-decoration:underline}#tl_versions{margin-bottom:0}#tl_versions th{background:#f6f6f8;padding:6px;border-top:1px solid #e9e9e9}#tl_versions th,#tl_versions td{border-bottom:1px solid #e9e9e9}#tl_versions td{padding:4px}#tl_versions td:first-child{white-space:nowrap}#tl_versions td:last-child{width:32px;white-space:nowrap;text-align:right}#tl_versions img.undo{padding-right:2px}#tl_versions .pagination{margin-top:18px;margin-bottom:14px}.tl_chmod{width:100%}.tl_chmod th{height:18px;text-align:center;font-weight:400;background:#f0f0f2}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_chmod th{font-weight:300}}.tl_chmod td{text-align:center;background:#f6f6f8}.tl_chmod th,.tl_chmod td{width:14.2857%;padding:6px;border:1px solid #fff}.tl_modulewizard button,.tl_optionwizard button,.tl_key_value_wizard button,.tl_tablewizard button,.tl_listwizard button,.tl_checkbox_wizard button,.tl_metawizard button,.tl_sectionwizard button{margin:0;padding:0;border:0;background:0 0}.tl_modulewizard{width:100%;max-width:800px;margin-top:2px}.tl_modulewizard td{position:relative;padding:0 3px 0 0}.tl_modulewizard th{font-size:.75rem;font-weight:400;padding:0 6px 1px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_modulewizard th{font-weight:300}}.tl_modulewizard td:last-child{width:1%;white-space:nowrap}.tl_modulewizard img{position:relative;top:1px}.js .tl_modulewizard input.mw_enable{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tl_modulewizard img.mw_enable{display:none}.js .tl_modulewizard img.mw_enable{display:inline;margin-right:1px}.tl_optionwizard{width:100%;max-width:600px}.tl_key_value_wizard{width:100%;max-width:450px}.tl_optionwizard,.tl_key_value_wizard{margin-top:2px}.tl_optionwizard label,.tl_key_value_wizard label{margin-right:3px}.tl_optionwizard td,.tl_key_value_wizard td{padding:0 3px 0 0}.tl_optionwizard th,.tl_key_value_wizard th{font-size:.75rem;font-weight:400;padding:0 6px 1px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_optionwizard th,.tl_key_value_wizard th{font-weight:300}}.tl_optionwizard td:nth-child(n+3),.tl_key_value_wizard td:nth-child(n+3){width:1%;white-space:nowrap}.tl_optionwizard img,.tl_key_value_wizard img{position:relative;top:1px}.tl_optionwizard .fw_checkbox,.tl_key_value_wizard .fw_checkbox{margin:0 1px}#tl_tablewizard{margin-top:2px;padding-bottom:2px;overflow:auto}.tl_tablewizard td{padding:0 3px 0 0}.tl_tablewizard thead td{padding-bottom:3px;text-align:center;white-space:nowrap}.tl_tablewizard tbody td:last-child{white-space:nowrap}.tl_tablewizard td.tcontainer{vertical-align:top}.tl_listwizard .tl_text{width:78%}.tl_checkbox_wizard .fixed{display:block;margin-top:1px}.tl_checkbox_wizard .sortable span{display:block}.tl_checkbox_wizard .sortable img{vertical-align:bottom}.tl_metawizard{margin:3px 0 6px}.tl_metawizard li{overflow:hidden;margin-bottom:2px;padding:9px;background:#f3f3f5}.tl_metawizard li.odd{background:#f9f9fb}.tl_metawizard span img{cursor:pointer}.tl_metawizard label{float:left;width:18%;margin-top:9px}.tl_metawizard .tl_text{float:left;width:82%;margin:1px 0}.tl_metawizard .tl_text+a{top:6px}.tl_metawizard br{clear:left}.tl_metawizard .lang{display:block;margin-bottom:9px;font-weight:600;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_metawizard .lang{font-weight:500}}.tl_metawizard_img{position:absolute;right:0;top:-1px}.tl_metawizard_new .tl_select{margin-right:4px;max-width:200px}.tl_metawizard_new .tl_submit{padding-top:6px;padding-bottom:6px}.tl_sectionwizard{margin-top:2px;width:100%;max-width:680px}.tl_sectionwizard td{width:25%;position:relative;padding:0 3px 0 0}.tl_sectionwizard th{font-size:.75rem;font-weight:400;padding:0 4px 1px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.tl_sectionwizard th{font-weight:300}}.tl_sectionwizard td:last-child{white-space:nowrap}#paste_hint{position:relative}.tl_message+#paste_hint{margin-top:-12px}#paste_hint p{position:absolute;font-family:"Architects Daughter",cursive;font-size:1rem;color:#838990;top:0;right:30px;padding:0 36px 24px 0;background:url(icons/arrow_right.svg) bottom right no-repeat;transform:rotate(-1deg)}.sort_hint{position:absolute;font-family:"Architects Daughter",cursive;font-size:1rem;color:#838990;top:-50px;left:160px;padding:0 6px 24px 42px;background:url(icons/arrow_left.svg) 6px bottom no-repeat;transform:rotate(-2deg)}.widget+.subpal .sort_hint{left:260px}.widget+.widget .sort_hint{left:320px}.serp-preview{max-width:600px;margin:2px 0;padding:4px 6px;font-family:Arial,sans-serif;font-weight:400;border:1px dotted #aaa;border-radius:2px}.serp-preview p{margin-bottom:0;line-height:1.3}.serp-preview .title{font-size:18px;color:#1a0dab}.serp-preview .url{color:#006621}.serp-preview .description{margin-top:2px;color:#545454}#tl_ajaxBox{width:20%;padding:2em;position:absolute;left:40%;background:#fff url(icons/loading.svg) no-repeat right 2em center;border:2px solid #111;border-radius:2px;font-size:1rem;text-align:left}#tl_ajaxOverlay{width:100%;height:100%;position:absolute;top:0;left:0;background:#fff;opacity:.5}.ce_gallery ul{overflow:hidden}.ce_gallery li{float:left;margin:0 6px 6px 0}.drag-handle{cursor:move}ul.sortable li{cursor:move;position:relative}ul.sortable li .dirname{display:none}ul.sortable li:hover .dirname{display:inline}ul.sortable button{position:absolute;top:0;right:0;border:0;background:#eee;margin:0;padding:0 0 3px;font-size:22px;line-height:9px;cursor:pointer;transition:all .1s linear}ul.sortable button:hover{background:#f9f9f9}ul.sortable button[disabled]{color:#999;cursor:not-allowed}ul.sortable button[disabled]:hover{background:rgba(255,255,255,.7)}#picker-menu{padding:9px 6px 0;border-bottom:1px solid #ddd}#picker-menu li{display:inline-block;padding:8px 0;background-color:#f9f9fb;border:1px solid #ddd;border-radius:2px 2px 0 0;position:relative;top:1px}#picker-menu li:hover{background-color:#f3f3f5}#picker-menu li.current{background-color:#f3f3f5;border-bottom-color:#f3f3f5}#picker-menu a{padding:3px 12px 3px 32px;background:url(icons/manager.svg) 12px center no-repeat}#picker-menu a:hover{color:#444}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#picker-menu a:hover{color:#222}}#picker-menu a.pagePicker{background-image:url(icons/pagemounts.svg);background-size:16px}#picker-menu a.filePicker{background-image:url(icons/filemounts.svg);background-size:14px}#picker-menu a.articlePicker{background-image:url(icons/articles.svg);background-size:16px}#picker-menu a.close{background-image:url(icons/back.svg)}.ace_editor{padding:3px}.ace_editor,.ace_editor *{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important;font-size:.75rem!important;color:#444}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.ace_editor,.ace_editor *{color:#222}}.ace-fullsize{overflow:hidden!important}.ace-fullsize .ace_editor{position:fixed!important;top:0;right:0;bottom:0;left:0;width:auto!important;height:auto!important;margin:0;border:0;z-index:10000}div.mce-edit-area{width:99.9%}time[title]{cursor:help}.float_left{float:left}.float_right{float:right}#manager{padding:9px 6px 0;border-bottom:1px solid #ddd}#manager a{padding:3px 12px 3px 32px;background:url(icons/manager.svg) 12px center no-repeat}.header_icon,.header_clipboard,.header_back,.header_new,.header_rss,.header_edit_all,.header_delete_all,.header_new_folder,.header_css_import,.header_theme_import,.header_store,.header_toggle,.header_sync{padding:3px 0 3px 21px;background-position:left center;background-repeat:no-repeat;margin-left:15px}.list_icon{margin-left:-3px;padding-left:20px;background-position:left center;background-repeat:no-repeat}.list_icon_new{width:16px;background-position:1px center;background-repeat:no-repeat}.header_clipboard{background-image:url(icons/clipboard.svg)}.header_back{background-image:url(icons/back.svg)}.header_new{background-image:url(icons/new.svg)}.header_rss{background-image:url(icons/rss.svg)}.header_edit_all{background-image:url(icons/all.svg)}.header_delete_all{background-image:url(icons/deleteAll.svg)}.header_new_folder{padding-left:24px;background-image:url(icons/newfolder.svg)}.header_css_import{background-image:url(icons/cssimport.svg)}.header_theme_import{background-image:url(icons/theme_import.svg)}.header_store{padding-left:18px;background-image:url(icons/store.svg)}.header_toggle{background-image:url(icons/folPlus.svg)}.header_sync{background-image:url(icons/sync.svg)}.tl_text_trbl,.tl_imageSize_0,.tl_imageSize_1,#ctrl_playerSize input{background:url(icons/hints.svg) no-repeat right 1px top 2px}#ctrl_playerSize_1,.tl_imageSize_1{background-position:right 1px top -28px!important}.trbl_top{background-position:right 1px top -59px!important}.trbl_right{background-position:right 1px top -89px!important}.trbl_bottom{background-position:right 1px top -119px!important}.trbl_left{background-position:right 1px top -149px!important}#ctrl_shadowsize_top{background-position:right 1px top -179px!important}#ctrl_shadowsize_right{background-position:right 1px top -209px!important}#ctrl_shadowsize_bottom{background-position:right 1px top -238px!important}#ctrl_shadowsize_left{background-position:right 1px top -269px!important}#ctrl_borderradius_top{background-position:left -299px!important}#ctrl_borderradius_right{background-position:right 1px top -329px!important}#ctrl_borderradius_bottom{background-position:right 1px top -352px!important}#ctrl_borderradius_left{background-position:left -382px!important}label.error,legend.error,.tl_checkbox_container.error legend{color:#c33}.tl_tbox .tl_error,.tl_box .tl_error{background:0 0;padding:0;margin-bottom:0;font-size:.75rem}.tl_formbody_edit>.tl_error{margin-top:9px}.broken-image{display:inline-block;padding:12px 12px 12px 30px;background:#faebeb url(icons/error.svg) no-repeat 9px center;color:#c33;text-indent:0}fieldset.tl_tbox,fieldset.tl_box{padding-top:9px;border-top:26px solid #f6f6f6;border-left:0;border-right:0}fieldset.tl_tbox.nolegend,fieldset.tl_box.nolegend{border-top:0}fieldset.tl_tbox>legend,fieldset.tl_box>legend{width:100%;box-sizing:border-box;color:#6a6a6c;padding:14px 0 0 28px;background:url(icons/navcol.svg) 13px 16px no-repeat;cursor:pointer}fieldset.collapsed{margin-bottom:0;padding-top:14px;padding-bottom:0}fieldset.collapsed div{display:none!important}fieldset.collapsed>legend{background:url(icons/navexp.svg) 13px 16px no-repeat}#tl_maintenance_cache table{width:100%}#tl_maintenance_cache th,#tl_maintenance_cache td{border-bottom:1px solid #e9e9e9}#tl_maintenance_cache th{background:#f6f6f8;padding:6px;border-top:1px solid #e9e9e9}#tl_maintenance_cache td{padding:6px;line-height:1.2}#tl_maintenance_cache tr:nth-child(even) td{background:#fcfcfe}#tl_maintenance_cache td span{color:#999}#tl_maintenance_cache td:first-child{width:16px}.mac #tl_maintenance_cache td:first-child .tl_checkbox{top:-2px}#tl_maintenance_cache .nw{white-space:nowrap}#tl_maintenance_cache .tl_checkbox_container{margin-top:12px}#tl_maintenance_cache .tl_checkbox_container label{font-weight:600}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#tl_maintenance_cache .tl_checkbox_container label{font-weight:500}}.pagination{overflow:hidden;background:#f6f6f8;margin-bottom:18px;border:solid #e9e9e9;border-width:1px 0;padding:12px 15px}.pagination ul{width:60%;float:right;text-align:right;padding-right:3px}.pagination p{width:30%;float:left;margin-bottom:0}.pagination li{display:inline;padding-right:3px}.pagination .active{color:#999}.pagination-lp{margin-left:15px;margin-right:15px}#sync-results{overflow:hidden;margin:18px 15px 0}#sync-results p{margin-bottom:0}#sync-results .left{float:left;padding:2px 0}#sync-results .right{float:right}#result-list{margin:15px}#result-list .tl_error,#result-list .tl_confirm,#result-list .tl_info,#result-list .tl_new{padding:3px 0;background:0 0}.dropzone{margin:2px 0;min-height:auto!important;border:3px dashed #ddd!important;border-radius:2px}.dropzone-filetree{display:none;position:absolute;top:0;left:0;width:100%;height:100%;opacity:.8;z-index:1}.dropzone-filetree-enabled{display:block}.dz-message span{font-size:1.3125rem;color:#ccc}@media (max-width:991px){body{background:#eaeaec}#header{width:100%;padding:0;position:fixed;top:0;z-index:2;transition:transform .2s ease;-webkit-transform:none;transform:none;will-change:transform}#container{display:block;padding-top:40px}#main,#left{float:none;overflow:hidden}#main{width:100%!important;position:relative;transition:transform .2s ease;-webkit-transform:none;transform:none;will-change:transform}.show-navigation #main{-webkit-transform:translateX(240px);transform:translateX(240px)}#left{position:absolute;top:40px;width:240px;transition:transform .2s ease;-webkit-transform:translateX(-240px);transform:translateX(-240px);will-change:transform}.show-navigation #left{-webkit-transform:none;transform:none}#tmenu .burger{display:inline}}@media (max-width:767px){#header.down{-webkit-transform:translateY(-40px);transform:translateY(-40px)}#header h1 a{width:22px;padding:12px;text-indent:34px;overflow:hidden}#tmenu>li>a{width:16px;margin-bottom:-2px;position:relative;overflow:hidden;white-space:nowrap;text-indent:28px;background-size:18px!important}#tmenu sup{top:6px;font-size:.5rem}#tmenu .icon-debug{background:url(icons/debug.svg) center center no-repeat}#tmenu .icon-preview{background:url(icons/preview.svg) center center no-repeat}#tmenu h2{width:16px;margin:0 0 -2px;padding-right:12px;overflow:hidden;white-space:nowrap;text-indent:28px;background:url(icons/profile.svg) center center no-repeat;background-size:18px}#main .content{margin:15px 10px}#main_headline{margin:15px 0;padding:0 11px}div.tl_tbox,div.tl_box{position:relative}.tl_content_left{width:100%;float:none}.showColumns th,.showColumns td{display:block}.showColumns th:empty{display:none}.tl_label{white-space:normal}.list_view .tl_listing img.theme_preview{display:none}.tl_filter{box-sizing:border-box;padding:0 3px 0 7px}.tl_filter strong{display:none}.tl_filter .tl_select{display:block;max-width:100%}.tl_search{width:76%;max-width:283px}.tl_search .tl_select{width:36%}.tl_search .tl_text{width:26%}.tl_sorting{width:60%;max-width:212px}.tl_limit{width:50%;max-width:177px}.tl_submit_panel{float:right;z-index:1}input.tl_submit{margin-top:3px;margin-bottom:3px;padding-left:6px!important;padding-right:7px!important}.tl_listing .tl_left,.tl_show td{word-break:break-word}#tl_breadcrumb li{padding:3px}#tl_versions{display:none}.tl_version_panel .tl_select{width:44%}.tl_modulewizard td:first-child{width:1%}.tl_modulewizard td:first-child .tl_select{max-width:52vw}#paste_hint,.sort_hint{display:none}#tl_maintenance_cache table{width:100%}#tl_maintenance_cache tr th:last-child,#tl_maintenance_cache tr td:last-child{display:none}.tl_file_list .ellipsis{padding-right:10px}}@media (max-width:599px){.tl_metawizard label{width:auto;float:none;font-size:.9em;display:block;margin-top:3px}.tl_metawizard .tl_text{width:100%}}@media (max-width:479px){.tl_modulewizard td:first-child .tl_select{max-width:48vw}} \ No newline at end of file diff --git a/core-bundle/src/Resources/contao/widgets/SerpPreview.php b/core-bundle/src/Resources/contao/widgets/SerpPreview.php new file mode 100644 index 00000000000..8c84eb70371 --- /dev/null +++ b/core-bundle/src/Resources/contao/widgets/SerpPreview.php @@ -0,0 +1,169 @@ +serpPreview['class'] ?? Model::getClassFromTable($this->strTable); + $model = $class::findByPk($this->activeRecord->id); + + if (!$model instanceof Model) + { + throw new \RuntimeException('Could not fetch the associated model'); + } + + if (!$model instanceof Routable && !isset($this->serpPreview['url'])) + { + throw new \LogicException('The model is not routable and no "url" parameter has been given'); + } + + $id = $model->id; + $title = StringUtil::substr($this->getTitle($model), 64); + $url = $this->serpPreview['url'] ?? $model->getAbsoluteUrl(); + $description = StringUtil::substr($this->getDescription($model), 160); + list($baseUrl) = explode($model->alias ?: $model->id, $url); + $urlSuffix = System::getContainer()->getParameter('contao.url_suffix'); + $suffix = substr($this->objDca->inputName, \strlen($this->objDca->field)); + $titleField = $this->getTitleField() . $suffix; + $titleFallbackField = $this->getTitleFallbackField() . $suffix; + $aliasField = $this->getAliasField() . $suffix; + $descriptionField = $this->getDescriptionField() . $suffix; + $descriptionFallbackField = $this->getDescriptionFallbackField() . $suffix; + + return << +

$title

+

$url

+

$description

+ + +EOT; + } + + private function getTitle(Model $model) + { + if (!isset($this->serpPreview['title'])) + { + return $model->title; + } + + if (\is_array($this->serpPreview['title'])) + { + return $model->{$this->serpPreview['title'][0]} ?: $model->{$this->serpPreview['title'][1]}; + } + + return $model->{$this->serpPreview['title']}; + } + + private function getDescription(Model $model) + { + if (!isset($this->serpPreview['description'])) + { + return $model->description; + } + + if (\is_array($this->serpPreview['description'])) + { + return $model->{$this->serpPreview['description'][0]} ?: $model->{$this->serpPreview['description'][1]}; + } + + return $model->{$this->serpPreview['description']}; + } + + private function getTitleField() + { + if (!isset($this->serpPreview['title'])) + { + return 'ctrl_title'; + } + + if (\is_array($this->serpPreview['title'])) + { + return 'ctrl_' . $this->serpPreview['title'][0]; + } + + return 'ctrl_' . $this->serpPreview['title']; + } + + private function getTitleFallbackField() + { + if (!isset($this->serpPreview['title']) || !\is_array($this->serpPreview['title'])) + { + return ''; + } + + return 'ctrl_' . $this->serpPreview['title'][1]; + } + + private function getAliasField() + { + if (!isset($this->serpPreview['alias'])) + { + return 'ctrl_alias'; + } + + return 'ctrl_' . $this->serpPreview['alias']; + } + + private function getDescriptionField() + { + if (!isset($this->serpPreview['description'])) + { + return 'ctrl_description'; + } + + if (\is_array($this->serpPreview['description'])) + { + return 'ctrl_' . $this->serpPreview['description'][0]; + } + + return 'ctrl_' . $this->serpPreview['description']; + } + + private function getDescriptionFallbackField() + { + if (!isset($this->serpPreview['description']) || !\is_array($this->serpPreview['description'])) + { + return ''; + } + + return 'ctrl_' . $this->serpPreview['description'][1]; + } +} diff --git a/news-bundle/src/EventListener/InsertTagsListener.php b/news-bundle/src/EventListener/InsertTagsListener.php index dc81138252b..e83c1b42885 100644 --- a/news-bundle/src/EventListener/InsertTagsListener.php +++ b/news-bundle/src/EventListener/InsertTagsListener.php @@ -13,7 +13,6 @@ namespace Contao\NewsBundle\EventListener; use Contao\CoreBundle\Framework\ContaoFramework; -use Contao\News; use Contao\NewsFeedModel; use Contao\NewsModel; use Contao\StringUtil; @@ -82,14 +81,11 @@ private function replaceNewsInsertTags(string $insertTag, string $idOrAlias, arr return ''; } - /** @var News $news */ - $news = $this->framework->getAdapter(News::class); - switch ($insertTag) { case 'news': return sprintf( '
%s', - $news->generateNewsUrl($model, false, \in_array('absolute', $flags, true)), + \in_array('absolute', $flags, true) ? $model->getAbsoluteUrl() : $model->getFrontendUrl(), StringUtil::specialchars($model->headline), $model->headline ); @@ -97,12 +93,12 @@ private function replaceNewsInsertTags(string $insertTag, string $idOrAlias, arr case 'news_open': return sprintf( '', - $news->generateNewsUrl($model, false, \in_array('absolute', $flags, true)), + \in_array('absolute', $flags, true) ? $model->getAbsoluteUrl() : $model->getFrontendUrl(), StringUtil::specialchars($model->headline) ); case 'news_url': - return $news->generateNewsUrl($model, false, \in_array('absolute', $flags, true)); + return \in_array('absolute', $flags, true) ? $model->getAbsoluteUrl() : $model->getFrontendUrl(); case 'news_title': return StringUtil::specialchars($model->headline); diff --git a/news-bundle/src/EventListener/PreviewUrlConvertListener.php b/news-bundle/src/EventListener/PreviewUrlConvertListener.php index 69418a89d16..558435ee410 100644 --- a/news-bundle/src/EventListener/PreviewUrlConvertListener.php +++ b/news-bundle/src/EventListener/PreviewUrlConvertListener.php @@ -14,7 +14,6 @@ use Contao\CoreBundle\Event\PreviewUrlConvertEvent; use Contao\CoreBundle\Framework\ContaoFramework; -use Contao\News; use Contao\NewsModel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -52,10 +51,7 @@ public function onPreviewUrlConvert(PreviewUrlConvertEvent $event): void return; } - /** @var News $newsAdapter */ - $newsAdapter = $this->framework->getAdapter(News::class); - - $event->setUrl($request->getSchemeAndHttpHost().'/'.$newsAdapter->generateNewsUrl($news)); + $event->setUrl($request->getSchemeAndHttpHost().'/'.$news->getFrontendUrl()); } private function getNewsModel(Request $request): ?NewsModel diff --git a/news-bundle/src/Resources/contao/classes/News.php b/news-bundle/src/Resources/contao/classes/News.php index b76a57b93d2..1fc0c306621 100644 --- a/news-bundle/src/Resources/contao/classes/News.php +++ b/news-bundle/src/Resources/contao/classes/News.php @@ -351,9 +351,14 @@ public function getSearchablePages($arrPages, $intRoot=0, $blnIsSitemap=false) * @param boolean $blnAbsolute * * @return string + * + * @deprecated Deprecated since Contao 4.9, to be removed in Contao 5.0; + * use NewsModel::getFrontendUrl() instead */ public static function generateNewsUrl($objItem, $blnAddArchive=false, $blnAbsolute=false) { + @trigger_error('Using News::generateNewsUrl() has been deprecated and will no longer work in Contao 5.0. Use NewsModel::getFrontendUrl() instead.', E_USER_DEPRECATED); + $strCacheKey = 'id_' . $objItem->id . ($blnAbsolute ? '_absolute' : ''); // Load the URL from cache diff --git a/news-bundle/src/Resources/contao/dca/tl_news.php b/news-bundle/src/Resources/contao/dca/tl_news.php index 8b76ec7b2c8..b6f198c2584 100644 --- a/news-bundle/src/Resources/contao/dca/tl_news.php +++ b/news-bundle/src/Resources/contao/dca/tl_news.php @@ -124,7 +124,7 @@ 'palettes' => array ( '__selector__' => array('addImage', 'addEnclosure', 'source', 'overwriteMeta'), - 'default' => '{title_legend},headline,alias,author;{date_legend},date,time;{meta_legend},pageTitle,description,serp_preview;{teaser_legend},subheadline,teaser;{image_legend},addImage;{enclosure_legend:hide},addEnclosure;{source_legend:hide},source;{expert_legend:hide},cssClass,noComments,featured;{publish_legend},published,start,stop' + 'default' => '{title_legend},headline,alias,author;{date_legend},date,time;{meta_legend},pageTitle,description,serpPreview;{teaser_legend},subheadline,teaser;{image_legend},addImage;{enclosure_legend:hide},addEnclosure;{source_legend:hide},source;{expert_legend:hide},cssClass,noComments,featured;{publish_legend},published,start,stop' ), // Subpalettes @@ -234,11 +234,12 @@ 'eval' => array('style'=>'height:60px', 'decodeEntities'=>true, 'tl_class'=>'clr'), 'sql' => "text NULL" ), - 'serp_preview' => array + 'serpPreview' => array ( - 'label' => &$GLOBALS['TL_LANG']['MSC']['serp_preview'], + 'label' => &$GLOBALS['TL_LANG']['MSC']['serpPreview'], 'exclude' => true, - 'input_field_callback' => array('tl_news', 'showSerpPreview') + 'inputType' => 'serpPreview', + 'eval' => array('serpPreview'=>array('title'=>array('pageTitle', 'headline'), 'description'=>array('description', 'teaser'))), ), 'subheadline' => array ( @@ -736,36 +737,6 @@ public function getArticleAlias(Contao\DataContainer $dc) return $arrAlias; } - /** - * Show the SERP preview - * - * @param Contao\DataContainer $dc - * - * @return string - */ - public function showSerpPreview(Contao\DataContainer $dc) - { - $news = Contao\NewsModel::findByPk($dc->activeRecord->id); - $url = Contao\News::generateNewsUrl($news, false, true); - $suffix = substr($dc->inputName, strlen($dc->field)); - - list($baseUrl) = explode($news->alias ?: $news->id, $url); - - $template = new Contao\FrontendTemplate('be_serp'); - $template->id = $news->id; - $template->title = $news->pageTitle ?: $news->headline; - $template->url = $url; - $template->description = $news->description ?: strip_tags($news->teaser); - $template->baseUrl = $baseUrl; - $template->titleField = 'ctrl_pageTitle' . $suffix; - $template->titleFallbackField = 'ctrl_headline' . $suffix; - $template->aliasField = 'ctrl_alias' . $suffix; - $template->descriptionField = 'ctrl_description' . $suffix; - $template->descriptionFallbackField = 'ctrl_teaser' . $suffix; - - return $template->parse(); - } - /** * Add the source options depending on the allowed fields (see #5498) * diff --git a/news-bundle/src/Resources/contao/models/NewsModel.php b/news-bundle/src/Resources/contao/models/NewsModel.php index b0d141e2ecf..9b6260e3cda 100644 --- a/news-bundle/src/Resources/contao/models/NewsModel.php +++ b/news-bundle/src/Resources/contao/models/NewsModel.php @@ -11,6 +11,7 @@ namespace Contao; use Contao\Model\Collection; +use Contao\Model\Routable; /** * Reads and writes news @@ -162,7 +163,7 @@ * * @author Leo Feyer */ -class NewsModel extends Model +class NewsModel extends Model implements Routable { /** * Table name @@ -170,6 +171,16 @@ class NewsModel extends Model */ protected static $strTable = 'tl_news'; + /** + * @var string + */ + private $strFrontendUrl; + + /** + * @var string + */ + private $strAbsoluteUrl; + /** * Find a published news item from one or more news archives by its ID or alias * @@ -411,6 +422,93 @@ public static function countPublishedFromToByPids($intFrom, $intTo, $arrPids, ar return static::countBy($arrColumns, array($intFrom, $intTo), $arrOptions); } + + /** + * {@inheritdoc} + */ + public function getFrontendUrl() + { + if (!$this->strFrontendUrl) + { + $this->strFrontendUrl = $this->getUrl('getFrontendUrl'); + } + + return $this->strFrontendUrl; + } + + /** + * {@inheritdoc} + */ + public function getAbsoluteUrl() + { + if (!$this->strAbsoluteUrl) + { + $this->strAbsoluteUrl = $this->getUrl('getAbsoluteUrl'); + } + + return $this->strAbsoluteUrl; + } + + /** + * Reset the URLs if the record is refreshed + * + * @param integer $intType + */ + public function refresh() + { + parent::refresh(); + + $this->strFrontendUrl = null; + $this->strAbsoluteUrl = null; + } + + /** + * Return the URL depending on the source + * + * @param $strMethod + * + * @return string + */ + private function getUrl($strMethod) + { + switch ($this->source) + { + // Link to an external page + case 'external': + if (0 === strncmp($this->url, 'mailto:', 7)) + { + return StringUtil::encodeEmail($this->url); + } + + return ampersand($this->url); + + // Link to an internal page + case 'internal': + if (($objTarget = $this->getRelated('jumpTo')) instanceof PageModel) + { + return $objTarget->$strMethod(); + } + break; + + // Link to an article + case 'article': + if (($objArticle = ArticleModel::findByPk($this->articleId)) instanceof ArticleModel && ($objPid = $objArticle->getRelated('pid')) instanceof PageModel) + { + return $objPid->$strMethod('/articles/' . ($objArticle->alias ?: $objArticle->id)); + } + break; + } + + // Link to the default page + $objPage = PageModel::findByPk($this->getRelated('pid')->jumpTo); + + if (!$objPage instanceof PageModel) + { + return ampersand(Environment::get('request')); + } + + return $objPage->$strMethod((Config::get('useAutoItem') ? '/' : '/items/') . ($this->alias ?: $this->id)); + } } class_alias(NewsModel::class, 'NewsModel'); diff --git a/news-bundle/src/Resources/contao/modules/ModuleNews.php b/news-bundle/src/Resources/contao/modules/ModuleNews.php index 9992e448b19..267a39ef745 100644 --- a/news-bundle/src/Resources/contao/modules/ModuleNews.php +++ b/news-bundle/src/Resources/contao/modules/ModuleNews.php @@ -79,6 +79,11 @@ protected function sortOutProtected($arrArchives) */ protected function parseArticle($objArticle, $blnAddArchive=false, $strClass='', $intCount=0) { + if ($blnAddArchive !== false) + { + @trigger_error('Passing true as second argument to ModuleNews::parseArticle() has been deprecated and will no longer work in Contao 5.0.', E_USER_DEPRECATED); + } + $objTemplate = new FrontendTemplate($this->news_template ?: 'news_latest'); $objTemplate->setData($objArticle->row()); @@ -98,7 +103,7 @@ protected function parseArticle($objArticle, $blnAddArchive=false, $strClass='', $objTemplate->hasSubHeadline = $objArticle->subheadline ? true : false; $objTemplate->linkHeadline = $this->generateLink($objArticle->headline, $objArticle, $blnAddArchive); $objTemplate->more = $this->generateLink($GLOBALS['TL_LANG']['MSC']['more'], $objArticle, $blnAddArchive, true); - $objTemplate->link = News::generateNewsUrl($objArticle, $blnAddArchive); + $objTemplate->link = $objArticle->getFrontendUrl(); $objTemplate->archive = $objArticle->getRelated('pid'); $objTemplate->count = $intCount; // see #5708 $objTemplate->text = ''; @@ -245,6 +250,11 @@ protected function parseArticle($objArticle, $blnAddArchive=false, $strClass='', */ protected function parseArticles($objArticles, $blnAddArchive=false) { + if ($blnAddArchive !== false) + { + @trigger_error('Passing true as second argument to ModuleNews::parseArticles() has been deprecated and will no longer work in Contao 5.0.', E_USER_DEPRECATED); + } + $limit = $objArticles->count(); if ($limit < 1) @@ -335,11 +345,11 @@ protected function getMetaFields($objArticle) * @return string * * @deprecated Deprecated since Contao 4.1, to be removed in Contao 5. - * Use News::generateNewsUrl() instead. + * Use NewsModel::getFrontendUrl() instead. */ protected function generateNewsUrl($objItem, $blnAddArchive=false) { - @trigger_error('Using ModuleNews::generateNewsUrl() has been deprecated and will no longer work in Contao 5.0. Use News::generateNewsUrl() instead.', E_USER_DEPRECATED); + @trigger_error('Using ModuleNews::generateNewsUrl() has been deprecated and will no longer work in Contao 5.0. Use NewsModel::getFrontendUrl() instead.', E_USER_DEPRECATED); return News::generateNewsUrl($objItem, $blnAddArchive); } @@ -356,12 +366,17 @@ protected function generateNewsUrl($objItem, $blnAddArchive=false) */ protected function generateLink($strLink, $objArticle, $blnAddArchive=false, $blnIsReadMore=false) { + if ($blnAddArchive !== false) + { + @trigger_error('Passing true as third argument to ModuleNews::generateLink() has been deprecated and will no longer work in Contao 5.0.', E_USER_DEPRECATED); + } + // Internal link if ($objArticle->source != 'external') { return sprintf( '', - News::generateNewsUrl($objArticle, $blnAddArchive), + $objArticle->getFrontendUrl(), StringUtil::specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['readMore'], $objArticle->headline), true), $strLink, ($blnIsReadMore ? '' : '') diff --git a/news-bundle/tests/EventListener/InsertTagsListenerTest.php b/news-bundle/tests/EventListener/InsertTagsListenerTest.php index f9e3fec5e67..0527c2ea617 100644 --- a/news-bundle/tests/EventListener/InsertTagsListenerTest.php +++ b/news-bundle/tests/EventListener/InsertTagsListenerTest.php @@ -12,7 +12,6 @@ namespace Contao\NewsBundle\Tests\EventListener; -use Contao\News; use Contao\NewsBundle\EventListener\InsertTagsListener; use Contao\NewsFeedModel; use Contao\NewsModel; @@ -47,23 +46,18 @@ public function testReplacesTheNewsTags(): void $newsModel->headline = '"Foo" is not "bar"'; $newsModel->teaser = '

Foo does not equal bar.

'; - $news = $this->mockAdapter(['generateNewsUrl']); - $news - ->method('generateNewsUrl') - ->willReturnCallback( - static function (NewsModel $model, bool $addArchive, bool $absolute): string { - if ($absolute) { - return 'http://domain.tld/news/foo-is-not-bar.html'; - } - - return 'news/foo-is-not-bar.html'; - } - ) + $newsModel + ->method('getFrontendUrl') + ->willReturn('news/foo-is-not-bar.html') + ; + + $newsModel + ->method('getAbsoluteUrl') + ->willReturn('http://domain.tld/news/foo-is-not-bar.html') ; $adapters = [ NewsModel::class => $this->mockConfiguredAdapter(['findByIdOrAlias' => $newsModel]), - News::class => $news, ]; $listener = new InsertTagsListener($this->mockContaoFramework($adapters)); diff --git a/news-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php b/news-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php index 1c874983783..d63c8256dd5 100644 --- a/news-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php +++ b/news-bundle/tests/EventListener/PreviewUrlConverterListenerTest.php @@ -14,7 +14,6 @@ use Contao\CoreBundle\Event\PreviewUrlConvertEvent; use Contao\CoreBundle\Framework\ContaoFramework; -use Contao\News; use Contao\NewsBundle\EventListener\PreviewUrlConvertListener; use Contao\NewsModel; use Contao\TestCase\ContaoTestCase; @@ -34,10 +33,14 @@ public function testConvertsThePreviewUrl(): void $requestStack->push($request); $newsModel = $this->createMock(NewsModel::class); + $newsModel + ->expects($this->once()) + ->method('getFrontendUrl') + ->willReturn('news/james-wilson-returns.html') + ; $adapters = [ NewsModel::class => $this->mockConfiguredAdapter(['findByPk' => $newsModel]), - News::class => $this->mockConfiguredAdapter(['generateNewsUrl' => 'news/james-wilson-returns.html']), ]; $framework = $this->mockContaoFramework($adapters);