-->

How can I make a Condition in TypoScript for loadi

2019-08-06 06:23发布

问题:

After a "long way" with Google, Searching and many tries:

I created a lib.variable for the current Page:

lib.currentPage = TEXT
lib.currentPage.data = page:uid

If I debug it in my FluidTemplate in the Frontend with:

Testing currentPage: <f:cObject typoscriptObjectPath="lib.currentPage" />

I got the correct value.


Now I want to use that Variable in a Condition in my pageSetup.ts like follows:

[DB:pages:lib.currentPage:backend_layout = pagets__pagelayout_logoclaim_subpage]
    page.includeJSFooter.belayoutlogoclaim = EXT:rm_base/Resources/Public/JS/be_logoclaim.js
[end]

I testet this with some other Conditions, but nothing works like expected.

Tested Conditions:

  • [page|backend_layout = pagelayout_logoclaim_subpage]
  • [globalVar = TSFE:page|backend_layout = pagelayout_logoclaim_subpage]

I also tested the Condition in the TypoScript Object Browser, and here it looks like good working:

TypoScript Object Browser - If I activate the Condition

SourceCode in the Frontend on a Site with the correct PageLayout

I need this, because I have two different Menus, and they need different JavaScripts, to avoid wrong behaviour in the Frontend.


Update: I inserted the pageLayouts like this:

page = PAGE
page {

    10 = FLUIDTEMPLATE
    10 {
        partialRootPath = EXT:rm_base/Resources/Private/Templates/Fluid/Partials/
        layoutRootPath = EXT:rm_base/Resources/Private/Templates/Fluid/Layouts/

        file.stdWrap.cObject = CASE
        file.stdWrap.cObject {
            key.data = pagelayout

            // Default-Template is LogoFull_Subpage (No Navigation Dependence)
            default = TEXT
            default.value = EXT:rm_base/Resources/Private/Templates/Fluid/LogoFull_Subpage.html

            // LogoClaim - Subpage
            pagets__pagelayout_logoclaim_subpage = TEXT
            pagets__pagelayout_logoclaim_subpage.value = EXT:rm_base/Resources/Private/Templates/Fluid/LogoClaim_Subpage.html
        }
    }

You see: The Backendlayouts are in Files of my Extension, not in the Database-Table: backend_layouts.

Update 2:

I would prefer a TypoScript-Way, if someone knows how - with external BE-Layouts. Thank you.

回答1:

As I've seen the prefix pagets__ ,I guess that the problem here is that the backend_layouts are not stored in the database, so I think that a condition about that would not work.

If you are using a different html template for each backend layout and you are running TYPO3 8.7.x there is a different way to solve this issue: Add to your template file a new section called:

<f:section name="FooterAssets">
<!--your code here-->
</f:section>

This section will be loaded just before the closing of </body>. As far as I remember you don't even have to call this section in your layout file.



回答2:

i would opt for using the VHS extension which provides an asset viewhelper.

you than include the asset view helper into the frontend template you are rendering. and it takes care about plaching the javascript in the header / footer it allows also to definde dependancies and loads the script in the correct order. also supports concatination / minification ...

an example include might look like this:

<v:asset.script path="EXT:your_ext/Resources/Public/JavaScript/menu_a.js" dependencies="jquery" />

this requires you that you specified "jquery" via typoscript (or another assit view helper)

example typoscript:

plugin.tx_vhs.settings.asset.jquery {
  path = EXT:your_ext/Resources/Public/JavaScript/jquery.js
  type = js
}


回答3:

I found another solution, that uses a TypoScript Custom Condition:

First I create a BackendlayoutCondition.php in my Extension here:

/Classes/TypoScript/BackendlayoutCondition.php

Its content is this (See Comments for more Detail):

<?php
namespace RM\RmBase\TypoScript;

use \TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractCondition;

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;;

class BackendlayoutCondition extends AbstractCondition
{
    /**
     * Evaluate condition
     *
     * @param array $conditionParameters
     * @return bool
     */
    public function matchCondition(array $conditionParameters)
    {
        \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($conditionParameters,'cond Params');

        # Return false if in Backend (Condition for Frontend only)
        if (!$GLOBALS['TSFE']) return false;

        # QueryBuilder for Table: pages
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');

        # Check if current BackendLayout is inside the $conditionParameters
        if (!empty($conditionParameters) && substr($conditionParameters[0], 0, 1) === '=') {
            # Trim the Parameter to get the correct Value of the Parameter (behind '=')
            $conditionParameters[0] = trim(substr($conditionParameters[0], 1));

                # Get Backendlayout on this Page
                $backendLayoutOnThisPage = $queryBuilder
                    ->select('backend_layout')
                    ->from('pages')
                    ->where(
                        $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(intval($GLOBALS['TSFE']->id), \PDO::PARAM_INT))
                    )
                    ->execute();

            # Store Backendlayout Value of the current Page in $backendLayoutOnThisPage
            $backendLayoutOnThisPage = $backendLayoutOnThisPage->fetch()['backend_layout'];
        } else {
            # If no ConditionParameter was set return false
            return false;
        }

        # Check if parent BackendLayout_NextLevel is inside the $conditionParameters
        if ($backendLayoutOnThisPage == '') {
            # Get pageRepository
            $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
            $pageRepository = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');

            # Get Rootline of the current Page
            $pageRootline = $pageRepository->getRootLine(intval($GLOBALS['TSFE']->id));

            # Set rootlineIndex to the Parent Page Index
            $rootlineIndex = count($pageRootline)-2;

            # Check Parent Page Backendlayout_NextLevel till 0 or Backendlayout found
            while ($rootlineIndex > 0) {
                if ($pageRootline[$rootlineIndex]['backend_layout_next_level'] == $conditionParameters[0]) {
                    return true;
                } else {
                    $rootlineIndex--;
                }
            }

            # No BackendLayout_NextLevel found till 0
            return false;
        } else {
            # If Condition Backendlayout found return true, otherwise return false
            if ($backendLayoutOnThisPage == $conditionParameters[0]) {
                return true;
            } else {
                return false;
            }
        }
    }
}

(Edited 2)

Than I just have to use the following Condition in my pageSetup.ts:

[RM\RmBase\TypoScript\BackendlayoutCondition = pagelayout_logoclaim_subpage]
    page.includeJSFooter.belayoutlogoclaim = EXT:rm_base/Resources/Public/JS/be_logoclaim.js
[global]

Now I have this Sourcecode in the Frontend:

<script src="/typo3conf/ext/rm_base/Resources/Public/JS/be_logoclaim.js?1523005944" type="text/javascript"></script>

not that:

<script src="/typo3conf/ext/rm_base/Resources/Public/JS/be_logoclaim.js" type="text/javascript"></script>

if I use the FooterAssets method:

<f:section name="FooterAssets">
    <script src="/typo3conf/ext/rm_base/Resources/Public/JS/be_logoclaim.js" type="text/javascript"></script>
</f:section>

Edit: I found some errors in my Answer, i fix it and edit my answer then.

Edit2: Now the Condition checks the Backendlayouts and the Backendlayouts_Nextlevel Fields for Backendlayouts to get all possible BE-Layouts including the inherited.



回答4:

The problem with the backend_layout field is that there also is a field backend_layout_next_level which affects subpages. so you can't build a simple condition.

Either you use stdWrap.if where you can calculate the current value for backend_layout overlaying an inherited value from backend_layout_next_level.
Or you define a userfunc where you evaluate it yourself in PHP.

Be aware that layouts defined in records have another prefix than layouts defined in pagesTS.


edit: Example

temp.layout = CASE
temp.layout {
    key.data = levelfield:-1, backend_layout_next_level, slide
    key.override.field = backend_layout

    default = TEXT
    default.value = default-layout

    1 = TEXT
    1.value = layoutdefinition_from_record

    pagets__layout2 = TEXT
    pagets__layout2.value = layoutdefinition_from_pageTSconfig

    sitepackage__layout3 = TEXT
    sitepackage__layout3.value = layoutdefinition_from_sitepackage 

}

Now you can use temp.layout for further decisions:

10 = TEXT
10.field = bodytext
10.wrap = <div class="demo">|</div>
10.wrap.if {
    equals.cObject < temp.layout
    value = default-layout
}