I copied my own build extension to a new Typo3 installation but now the backend template is not generated correctly anymore. In the "old" installation it is still working. The extension has a configuration menu in the backend that uses the list template. It should load the following template:
/ext/resources/backend/customers/list.html
But the extension loads the following instead:
/ext/resources/customers/list.html
In the ext_tables.php it is registered as follow:
if (TYPO3_MODE === 'BE') {
/**
* Registers a Backend Module
*/
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule(
'MTR.' . $_EXTKEY,
'user', // Make module a submodule of 'user'
'mtcus', // Submodule key
'', // Position
array(
'Customers' => 'list',
),
array(
'access' => 'user,group',
'icon' => 'EXT:' . $_EXTKEY . '/ext_icon.gif',
'labels' => 'LLL:EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_mtcus.xlf',
)
);
}
After so much of investigation and reference I could able to find the issue with the plugin. When I created back-end module with Extension Builder the default TS configurations where created like. For example consider the extension key is testextension and the BE Module key is custommodulebe in TS file the module template path was registered like.
IN constants.txt file
module.tx_testextension_custommodulebe {
view {
# cat=module.tx_testextension_custommodulebe/file; type=string; label=Path to template root (BE)
templateRootPath = EXT:testextension/Resources/Private/Backend/Templates/
# cat=module.tx_testextension_custommodulebe/file; type=string; label=Path to template partials (BE)
partialRootPath = EXT:testextension/Resources/Private/Backend/Partials/
# cat=module.tx_testextension_custommodulebe/file; type=string; label=Path to template layouts (BE)
layoutRootPath = EXT:testextension/Resources/Private/Backend/Layouts/
}
persistence {
# cat=module.tx_testextension_custommodulebe//a; type=string; label=Default storage PID
storagePid =
}
}
IN setup.txt
module.tx_testextension_custommodulebe {
persistence {
storagePid = {$module.tx_testextension_custommodulebe.persistence.storagePid}
}
view {
templateRootPath = {$module.tx_testextension_custommodulebe.view.templateRootPath}
partialRootPath = {$module.tx_testextension_custommodulebe.view.partialRootPath}
layoutRootPath = {$module.tx_testextension_custommodulebe.view.layoutRootPath}
}
}
Fix was we only need to define the extension key in this module
configuration.
Corrected Solution
constants.txt
module.tx_testextension {
view {
# cat=module.tx_testextension/file; type=string; label=Path to template root (BE)
templateRootPath = EXT:testextension/Resources/Private/Backend/Templates/
# cat=module.tx_testextension/file; type=string; label=Path to template partials (BE)
partialRootPath = EXT:testextension/Resources/Private/Backend/Partials/
# cat=module.tx_testextension/file; type=string; label=Path to template layouts (BE)
layoutRootPath = EXT:testextension/Resources/Private/Backend/Layouts/
}
persistence {
# cat=module.tx_testextension//a; type=string; label=Default storage PID
storagePid =
}
}
setup.txt
# Module configuration
module.tx_testextension {
persistence {
storagePid = {$module.tx_testextension.persistence.storagePid}
}
view {
templateRootPath = {$module.tx_testextension.view.templateRootPath}
partialRootPath = {$module.tx_testextension.view.partialRootPath}
layoutRootPath = {$module.tx_testextension.view.layoutRootPath}
}
}
Try to implement the static TypoScript template of your Extension.
Related
I have an extbase extension with this TCA:
$GLOBALS['TCA']['tt_content']['types']['list']['previewRenderer']['items_item']
= \Vendor\Name\Backend\Preview\PreviewRenderer::class;
and this tsconfig:
mod.web_layout.tt_content.preview.list.items_item = EXT:EXT/Resources/Private/Templates/Preview/Items.html
Everything works well if i write the complete Code in this template file. But if i change it and use Partials like this:
<f:render arguments="{_all}" partial="Preview/List"/>
I only get the following error:
Error while rendering FluidTemplate preview using /typo3conf/ext/EXT/Resources/Private/Templates/Preview/Items.html The Fluid template files "" could not be loaded.
How can i set the Partial and Layout path?
Ive tried ist with module via typoscript but it doesnt work.
It depends on what your PreviewRender is doing.
The StandardContentPreviewRenderer supports only a template-file, no layouts, no partials. It's using a FluidStandaloneView and only setting setTemplatePathAndFilename() without setting paths for other parts of the template (renderContentElementPreviewFromFluidTemplate()):
protected function renderContentElementPreviewFromFluidTemplate(array $row): ?string
{
$tsConfig = BackendUtility::getPagesTSconfig($row['pid'])['mod.']['web_layout.']['tt_content.']['preview.'] ?? [];
$fluidTemplateFile = '';
if ($row['CType'] === 'list' && !empty($row['list_type'])
&& !empty($tsConfig['list.'][$row['list_type']])
) {
$fluidTemplateFile = $tsConfig['list.'][$row['list_type']];
} elseif (!empty($tsConfig[$row['CType']])) {
$fluidTemplateFile = $tsConfig[$row['CType']];
}
if ($fluidTemplateFile) {
$fluidTemplateFile = GeneralUtility::getFileAbsFileName($fluidTemplateFile);
if ($fluidTemplateFile) {
try {
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setTemplatePathAndFilename($fluidTemplateFile);
$view->assignMultiple($row);
if (!empty($row['pi_flexform'])) {
$flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
$view->assign('pi_flexform_transformed', $flexFormService->convertFlexFormContentToArray($row['pi_flexform']));
}
return $view->render();
} catch (\Exception $e) {
$this->logger->warning('The backend preview for content element {uid} can not be rendered using the Fluid template file "{file}"', [
'uid' => $row['uid'],
'file' => $fluidTemplateFile,
'exception' => $e,
]);
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] && $this->getBackendUser()->isAdmin()) {
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->assign('error', [
'message' => str_replace(Environment::getProjectPath(), '', $e->getMessage()),
'title' => 'Error while rendering FluidTemplate preview using ' . str_replace(Environment::getProjectPath(), '', $fluidTemplateFile),
]);
$view->setTemplateSource('<f:be.infobox title="{error.title}" state="2">{error.message}</f:be.infobox>');
return $view->render();
}
}
}
}
return null;
}
If you want more advanced features in your preview, you have to extend/override this method.
Update:
StandaloneView extends TYPO3\CMS\Fluid\View\AbstractTemplateView, so you have also those setters:
setTemplate($templateName)
setTemplatePathAndFilename($templatePathAndFilename)
setTemplateRootPaths(array $templateRootPaths)
setPartialRootPaths(array $partialRootPaths)
setLayoutRootPaths(array $layoutRootPaths)
So setting paths for partials in your renderContentElementPreviewFromFluidTemplate() should solve it:
$view->setPartialRootPaths([
\TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName('EXT:extensionfolder/Resources/Private/Partials'),
]);
I am using cobj_xpath object in my page typoscript as follows.
lib.xpath = XPATH
lib.xpath {
source = http://docsouth.unc.edu/southlit/poe/poe.xml
return = string
resultObj {
cObjNum = 1
1.current = 1
}
}
page.10 = FLUIDTEMPLATE
page.10.variables {
title < lib.xpath
title.expression = /TEI.2/text/front/titlePage/docTitle/titlePart
author < lib.xpath
author.expression = /TEI.2/text/front/titlePage/docAuthor
}
I can access the 'title' and 'author' variables in page template successfully via {title} and {author} viewhelpers but I cannot access them in the content element level. I cannot even find them in at CE level. Also I have the same problem with other COAs e.g.:
taleArgument = TEXT
taleArgument.data = GP:tale
MORE INFO:
I have created the CE via mask extension and configured it to create the required files in /Resources/Mask/ folder. In this folder there is a json file which contains the CE configuration and two folders named Backend and Frontend. Each of these folders contain Layout/Partial/Templates folders. I have inserted the CE created by mask in one of my pages. I manipulate the HTML file in Frontend/Templates as the template file and I can access the fields which I have created in the CE backend properly, so I suppose that my configuration is working well to this end.
Typo3 Version: 9.5.19
cobj_xpath and cobj_xslt version: 1.9.0
Further Investigations:
To get rid of external extensions, I installed a fresh Typo3. Then I developed a CE in my sitepackage from scratch. My configuration follows:
my_ext/Configuration/TsConfig/Page/Mod/Wizards/NewContentElement.tsconfig
mod.wizards.newContentElement.wizardItems.common {
elements {
my_ext_newcontentelement {
iconIdentifier = folder-open
title = Registration Example
description = Create a registration form
tt_content_defValues {
CType = my_ext_newcontentelement
}
}
}
show := addToList(my_ext_newcontentelement)
}
my_ext/Configuration/TCA/Overrides/tt_content.php
<?php
defined('TYPO3_MODE') or die();
call_user_func(function () {
// Adds the content element to the "Type" dropdown
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
'tt_content',
'CType',
[
'Registration Example',
'my_ext_newcontentelement',
'form-checkbox',
],
'textmedia',
'after'
);
// Configure the default backend fields for the content element
$GLOBALS['TCA']['tt_content']['types']['my_ext_newcontentelement'] = [
'showitem' => '
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
--palette--;;general,
--palette--;;headers,
bodytext;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:bodytext_formlabel,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
--palette--;;language,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
--palette--;;hidden,
--palette--;;access,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
categories,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,
rowDescription,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
',
'columnsOverrides' => [
'bodytext' => [
'config' => [
'enableRichtext' => true,
'richtextConfiguration' => 'default',
],
],
],
];
});
my_ext/Configuration/TypoScript/setup.typoscript
lib.contentElement {
templateRootPaths.200 = EXT:my_ext/Resources/Private/Templates/ContentElements/
}
tt_content {
my_ext_newcontentelement =< lib.contentElement
my_ext_newcontentelement {
templateName = NewContentElement
}
}
my_ext/Resources/Private/Templates/ContentElements/NewContentElement.html:
<div>{data.bodytext -> f:format.html()}</div>
I tested my CE after adding one to the backend and it works fine so far.
Then I create a new variable in my_ext/Configuration/TypoScript/setup.typoscript:
page.10.variables {
test = TEXT
test.value = test
}
I can see the variable when I add {_all} to my page template:
but no luck when I try to catch it in my CE template:
TLDR:
each fluid rendering has it's own variables. There are no global fluid-variables.
It is obvious that you can not access test from your content element as the definition of page.10.variables results in fluid variables used while you are renderend the page-template (page.10).
In your content element you have an independent rendering with it's own set of variables.
Meanwhile you often have fluid for some rendering, but each has its own definition and variable set.
The whole page has a page fluid rendering.
Each plugin has it's own fluid rendering, probably for each action. Although they share a common extension setting which results in some common fluid variables.
Each content element has a Fluid rendering, though they might share some definition as the result from the same kind of data (a tt_content record). The kind of CE defines which template is used to start with and there are different renderings.
Using TYPO9 and ext:bootstrap_package (and ext_fluid_styled_content) you can find:
The rendering of the CEs is defined below tt_content. with the name of the CE as next key. All definitions are based on lib.dynamicContent
if you want to access any data independent from context in your fluid you could use typoscript viewhelpers like:
lib.text = TEXT
lib.text.value = test
lib.getText = TEXT
lib.getText.data = GP:text
the calls in fluid:
<f:cObject typoscriptObjectPath="lib.text" />
{f:cObject(typoscriptObjectPath:'lib.getText')}
I am trying to override a Marker within my Typoscript with content rendered by my custom created extension.
As far as I know It should work like this (Where MENU_PRODUKT_CATEGORIES) is my Marker:
MENU_PRODUKT_CATEGORIES = COA
MENU_PRODUKT_CATEGORIES {
10 = USER
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = MoTimeProducts
pluginName = Products
vendorName = products
controller = Category
action = parentList
}
}
The extensionName and related configurations also seem correct to me. When I var_dump() my ext_localconf.php configuratin this is displayed:
My first Parameter where MoTimeProducts is my extensionName and products my vendorName. Is this correct?
MoTimeProducts.products
The second Parameter should be the pluginName and seems ok, too.
Products
This is how my complete ext_localconf configuration looks like:
<?php
if (!defined('TYPO3_MODE')) {
die('Access denied.');
}
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'MoTimeProducts.' . $_EXTKEY,
'Products',
array(
'Category' => 'list, parentList',
'Product' => 'list, show, filter, ajaxFilter, refList',
'Formular' => 'display'
),
// non-cacheable actions
array(
'Category' => '',
'Product' => 'ajaxFilter, list',
'Formular' => 'display'
)
);
My Controller and Action configuration seems fine also. Below my action within the CategoryController
/**
* action list
*
* #return void
*/
public function parentListAction() {
$this->view->assign('categories', $currentCategory = $this->categoryRepository->getHighestLevelCategories($GLOBALS['TSFE']->sys_language_uid));
}
I also have a flex form for the Backend configuration and inserting plugins could this also be a reason?
Thx for reading.
Oh wow it was
MENU_PRODUKT_CATEGORIES = COA
MENU_PRODUKT_CATEGORIES {
10 = USER
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
pluginName = Products
extensionName = Products
vendorName = MoTimeProducts
controller = Category
action = list
switchableControllerActions {
Category {
1 = parentList
}
}
}
}
Where vendorName with a combination of lowercased plugin name is the first paramater for the plugin configuration.
Edit: Turns out it is very bad practice to have the same name for the plugin/extension which can lead to confusion and errors. One should avoid doing it like I did at all cost!
In TYPO3 CMS 6.2.17, I used Extension Builder to make an Extbase extension that has a frontend plugin and a backend module. I built a localhost website with two pages: id=1 is a standard page; and id=2 is a folder. The standard page has the site's root TypoScript template, and that template includes my extension's static file.
I activated my Extbase extension in the Web module. When I selected my extension and the folder page (id=2), I saw a populated listing display from the default controller and action; but the display was using the frontend Fluid layout, not the backend layout. I want the backend layout for its Fluid actionMenu in the "typo3-docheader-functions" div class.
I can't seem to get the backend Fluid layout for the display. I've selected the standard page (empty listing display as expected) and even the site root page (id=0) (also empty listing display), but they both use the frontend Fluid layout, too.
I've cleared all caches and cleaned typo3temp/ in the Install Tool. I've deactivated and reactivated my extension in Extension Manager. I've tried solutions suggested in TYPO3 Extbase backend module. Template path issue and even TYPO3 4.5 extbase test backend module. Nothing has worked so far. I've even gone through the site's Install Tool "all configuration" settings, but saw nothing I thought could affect the backend display problem.
The code is straight from Extension Builder, but here are some excerpts.
ext_tables.php:
if (TYPO3_MODE === 'BE') {
/**
* Registers a Backend Module
*/
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule(
'MyVendor.' . $_EXTKEY,
'web',
'myextbe', // Submodule key
'', // Position
array(
'Import' => 'list, show, new, create, edit, update, delete',
'Pages' => 'list, show',
),
array(
'access' => 'user,group',
'icon' => 'EXT:' . $_EXTKEY . '/ext_icon.gif',
'labels' => 'LLL:EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_myextbe.xlf',
)
);
}
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'My Ext');
myext\Configuration\TypoScript\constants.txt:
module.tx_myext_myextbe {
view {
# cat=module.tx_myext_myextbe/file; type=string; label=Path to template root (BE)
templateRootPath = EXT:myext/Resources/Private/Backend/Templates/
# cat=module.tx_myext_myextbe/file; type=string; label=Path to template partials (BE)
partialRootPath = EXT:myext/Resources/Private/Backend/Partials/
# cat=module.tx_myext_myextbe/file; type=string; label=Path to template layouts (BE)
layoutRootPath = EXT:myext/Resources/Private/Backend/Layouts/
}
persistence {
# cat=module.tx_myext_myextbe//a; type=string; label=Default storage PID
storagePid =2
}
}
myext\Configuration\TypoScript\setup.txt:
# Module configuration
module.tx_myext_myextbe {
persistence {
storagePid = {$module.tx_myext_myextbe.persistence.storagePid}
}
view {
templateRootPath = {$module.tx_myext_myextbe.view.templateRootPath}
partialRootPath = {$module.tx_myext_myextbe.view.partialRootPath}
layoutRootPath = {$module.tx_myext_myextbe.view.layoutRootPath}
}
}
Replace all module.tx_myext_myextbe to module.tx_myext and plugin.tx_myext_myextfe to plugin.tx_myext.
module.tx_myext_myextbe is invalid notation in 6.2.x - in the result Extbase can't find it and tries the default template path which is frontend one
constants.txt
module.tx_myext {
view {
# cat=module.tx_myext/file; type=string; label=Path to template root (BE)
templateRootPath = EXT:myext/Resources/Private/Backend/Templates/
# cat=module.tx_myext/file; type=string; label=Path to template partials (BE)
partialRootPath = EXT:myext/Resources/Private/Backend/Partials/
# cat=module.tx_myext/file; type=string; label=Path to template layouts (BE)
layoutRootPath = EXT:myext/Resources/Private/Backend/Layouts/
}
persistence {
# cat=module.tx_myext//a; type=string; label=Default storage PID
storagePid = 2
}
}
setup.txt
module.tx_myext {
persistence {
storagePid = {$module.tx_myext.persistence.storagePid}
}
view {
templateRootPath = {$module.tx_myext.view.templateRootPath}
partialRootPath = {$module.tx_myext.view.partialRootPath}
layoutRootPath = {$module.tx_myext.view.layoutRootPath}
}
}
TypoScript Object browser
[module]
[tx_myext]
[view]
[templateRootPath] = EXT:myext/Resources/Private/Backend/Templates/
[partialRootPath] = EXT:myext/Resources/Private/Backend/Partials/
[layoutRootPath] = EXT:myext/Resources/Private/Backend/Layouts/
I have a plugin http://typo3.org/extensions/repository/view/aw_consume
I'm using it as a content element it's working
When I try to assign to a subpart in my typoscript nothing shows up
LOGOUT < plugin.tx_awconsume.widgets.menu
this plugin was created with the extension_builder extension installed on TYPO3 6.1.4
update 3
plugin.tx_awconsume {
view {
templateRootPath = {$plugin.tx_awconsume.view.templateRootPath}
partialRootPath = {$plugin.tx_awconsume.view.partialRootPath}
layoutRootPath = {$plugin.tx_awconsume.view.layoutRootPath}
}
persistence {
storagePid = {$plugin.tx_awconsume.persistence.storagePid}
}
features {
# uncomment the following line to enable the new Property Mapper.
# rewrittenPropertyMapper = 1
}
widgets {
menu = USER
menu {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
pluginName = FeAwConsume
extensionName = AwConsume
controller = ConsumerItem
action = list
vendorName = Alexweb
}
}
}
ext_tables.php
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
$_EXTKEY,
'FeAwConsume',
'fe_awconsume'
);
ext_localconf.php
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Alexweb.' . $_EXTKEY,
'FeAwConsume',
array(
'ConsumerItem' => 'list, show, new, create, delete',
),
// non-cacheable actions
array(
'ConsumerItem' => 'create, delete',
)
);
I have updated the code snippets according to #lorenz answer but im still getting no output
I have also pushed the latest version in TER 0.1.5
update 4
I did manage to get the expected output only after adding
plugin.tx_awconsume.widgets {
menu = USER
menu {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
pluginName = FeAwConsume
extensionName = AwConsume
controller = ConsumerItem
action = list
vendorName = Alexweb
}
}
To the template typoscript file from \typo3conf\ext\aw_consume\Configuration\TypoScript\setup.txt
Where it was originally placed by the extension_builder extension however I got a feeling that this is not really a good idea
If you have a close look at your ext_localconf.php, you will notice that you use a vendor name. The vendor name should start with Uppercase so your ext_localconf.php should read:
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Alexweb.' . $_EXTKEY,
'MyPlugin',
array(
'ConsumerItem' => 'list, show, new, create, delete',
),
array(
'ConsumerItem' => 'create, delete',
)
);
Your ext_tables.php should look like this:
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
$_EXTKEY,
'MyPlugin',
'Speaking name of my plugin'
);
The TypoScript object of your plugin should include the vendor name (the property is vendorName, not vendor):
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
pluginName = MyPlugin
extensionName = AwConsume
vendorName = Alexweb
controller = ConsumerItem
action = list
Keep in mind that your classes also must include the vendor name/make use of the correct namespace:
namespace Alexweb\AwConsume\Controller;
class ConsumerItemController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
}
Then you should be fine.
The extension name is the UpperCamelCase variant of your extension key, so if your extension key is "aw_consume", your extension name is "AwConsume". This name is used in the classes
The plugin name is the name of a particular plugin that is part of your extension. Since there can be many plugins in an extension, you should choose a fitting name for it. The plugin name should also be UpperCamelCase. You can have multiple plugins for the same controllers, therefore the plugin doesn't have to be named like the controller.
See also http://forge.typo3.org/projects/typo3v4-mvc/wiki/FAQ#What-is-the-Extension-Name