TYPO3 Render FLUID Template in Backend - typo3

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'),
]);

Related

TYPO3 I got an error by list after the installation of my own plugin

My TYPO3 version is 10.4.21 and I use extensions (Fluid styled content, sitepackage, Bootstrap, pizpalue and my own plugin which I made).
I created a plugin which names New Flipbox, because I have to make a new content element with a function of flipbox for my project work. But I have an error.
If I click a list button on the menu on the left side, an error occurred:
Oops, an error occurred! An exception occurred while executing 'SELECT
uid FROM tx_myextensionkey_domain_model_newflipbox WHERE
(tx_myextensionkey_domain_model_newflipbox.pid = ?) AND
((tx_myextensionkey_domain_model_newflipbox.deleted = 0) AND
((tx_myextensionkey_domain_model_newflipbox.t3ver_wsid = 0) AND
(tx_myextensionkey_domain_model_newflipbox.t3ver_oid = 0)))
LIMIT 1' with params [1]: SQLSTATE[42S02]: Base table or view not
found: 1146 Table
'd037b84f.tx_rsnmizukiflipbox_domain_model_newflipbox' doesn't exist
How can I fix it?
For now, I've written down these:
in /typo3conf/ext/myextension/Configuration/TCA/Overrides/tt_content.php:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(
array(
'My Flipbox',
'rsnflipbox',
'EXT:core/Resources/Public/Icons/T3Icons/content/content-carousel-image.svg'
),
'CType',
'myextensionkey'
);
// Configure the default backend fields for the content element
$GLOBALS['TCA']['tt_content']['types']['flipbox_contentelement'] = [
'showitem' => '
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
--palette--;;general,
header; Internal title (not displayed),
bodytext;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:bodytext_formlabel,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
--palette--;;hidden,
--palette--;;access,
',
'columnsOverrides' => [
'bodytext' => [
'config' => [
'enableRichtext' => true,
'richtextConfiguration' => 'default',
],
],
],
];
in /typo3conf/ext/myextension/ext_location.php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(
'mod {
wizards.newContentElement.wizardItems.plugins {
elements {
newflipbox {
iconIdentifier = content-dashboard
title = LLL:EXT:myextensionkey/Resources/Private/Language/locallang_db.xlf:tx_myextensionkey_newflipbox.name
description = LLL:EXT:myextensionkey/Resources/Private/Language/locallang_db.xlf:tx_myextensionkey_newflipbox.description
tt_content_defValues {
CType = list
list_type = key_newflipbox
}
}
}
show = *
}
}'
);
// wizards bei Plugin
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(
'mod {
wizards.newContentElement.wizardItems.interactive {
elements {
newflipbox {
iconIdentifier = content-dashboard
title = LLL:EXT:myextensionkey/Resources/Private/Language/locallang_db.xlf:tx_myextensionkey_newflipbox.name
description = LLL:EXT:myextensionkey/Resources/Private/Language/locallang_db.xlf:tx_myextensionkey_newflipbox.description
tt_content_defValues {
CType = list
list_type = key_newflipbox
}
}
}
show = *
}
}'
);
$iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class);
$iconRegistry->registerIcon(
'myextensionkey-plugin-newflipbox',
\TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
['source' => 'EXT:myextensionkey/Resources/Public/Icons/user_plugin_newflipbox.svg']
);
});
in /typo3conf/ext/myextension/Configuration/TypoScript/setup.typoscript
lib.contentElement {
templateRootPaths.200 = EXT:myextensionkey/Resources/Private/Templates/
}
lib.contentElement {
partialRootPaths.200 = EXT:myextensionkey/Resources/Private/Partials/
}
lib.contentElement {
layoutRootPaths.200 = EXT:myextensionkey/Resources/Private/Layouts/
}
tt_content {
flipbox_contentelement =< lib.contentElement
flipbox_contentelement {
templateName = NewContentElement
}
}
I saw a website of TYPO3(https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/ContentElements/AddingYourOwnContentElements.html) to create a element content, but I can't go on because of some errors.
What should I do now? I hope someone can help me.
Thank you.
The error message clearly states that the table tx_rsnmizukiflipbox_domain_model_newflipbox is missing. So you should check if you have added ext_tables.sql with the necessary database fields and then you should go to the install tool and do a database compare to create the missing table.

SysFolder Icons with TYPO3 Icon-API

Till TYPO3 CMS 6.2 i've been using the following code in extTables.php to provide sysfolder icons:
$TCA['pages']['columns']['module']['config']['items'][] = array('Templates', 'templates', '/fileadmin/icons/application_side_list.png');
\TYPO3\CMS\Backend\Sprite\SpriteManager::addTcaTypeIcon('pages', 'contains-templates', '/fileadmin/icons/application_side_list.png');
As since 7.6 the code is obsolete and icons are provided by the Icon-API. Am I right? So my question is, if it's still possible to provide sysfolder icons to the backend using BitmapIconProvider, SvgIconProvider or the FontawesomeIconProvider?
Yes, this should work using the IconRegistry core class:
ext_localconf.php:
if (TYPO3_MODE === 'BE') {
/** #var \TYPO3\CMS\Core\Imaging\IconRegistry $iconRegistry */
$iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class);
$iconRegistry->registerIcon(
'apps-pagetree-folder-contains-templates',
\TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider::class,
['source' => 'EXT:myext/Resources/Public/Icons/application_side_list.png']
);
}
ext_tables.php:
if (TYPO3_MODE === 'BE') {
$GLOBALS['TCA']['pages']['columns']['module']['config']['items'][] = [
0 => 'Templates',
1 => 'templates',
2 => 'apps-pagetree-folder-contains-templates'
];
}
The TYPO3 extension must be modified to fit the needs of TYPO3 7.5 and higher. Replace myextkey by the extension key of your extension.
ext_localconf.php:
if (TYPO3_MODE == 'BE') {
$pageType = 'myext10'; // a maximum of 10 characters
$icons = array(
'apps-pagetree-folder-contains-' . $pageType => 'apps-pagetree-folder-contains-myextkey.svg'
);
/** #var \TYPO3\CMS\Core\Imaging\IconRegistry $iconRegistry */
$iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class);
foreach ($icons as $identifier => $filename) {
$iconRegistry->registerIcon(
$identifier,
$iconRegistry->detectIconProvider($filename),
array('source' => 'EXT:' . $_EXTKEY . '/Resources/Public/Icons/' . $filename)
);
}
}
Configuration/TCA/Overrides/pages.php:
<?php
if (!defined ('TYPO3_MODE')) {
die ('Access denied.');
}
// add folder icon
$pageType = 'myext10'; // a maximum of 10 characters
$iconReference = 'apps-pagetree-folder-contains-' . $pageType;
$addToModuleSelection = TRUE;
foreach ($GLOBALS['TCA']['pages']['columns']['module']['config']['items'] as $item) {
if ($item['1'] == $pageType) {
$addToModuleSelection = false;
break;
}
}
if ($addToModuleSelection) {
$GLOBALS['TCA']['pages']['ctrl']['typeicon_classes']['contains-' . $pageType] = $iconReference;
$GLOBALS['TCA']['pages']['columns']['module']['config']['items'][] = array(
0 => 'LLL:EXT:myextkey/locallang.xml:pageModule.plugin',
1 => $pageType,
2 => $iconReference
);
}
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerPageTSConfigFile(
$pageType,
'Configuration/TSconfig/Page/folder_tables.txt',
'EXT:myextkey :: Restrict pages to myextkey records'
);
locallang.xml:
<label index="pageModule.plugin">My Extension: Table names of my extension</label>
Resources/Public/Icons/apps-pagetree-folder-contains-myextkey.svg:
vector graphic image file for your extension tables
see https://github.com/TYPO3/TYPO3.Icons for working example SVG icons.
Configuration/TSconfig/Page/folder_tables.txt:
Insert the table names of your extension.
mod.web_list.allowedNewTables = tx_myextkey_tablename1, tx_myextkey_tablename2, tx_myextkey_tablename3

Moodle multi-select: linking over items

I'm trying to use the multi-select form element in a Moodle database to generate a list of tags. I would like these tags to link to the relevant search page displaying the filtered results.
The following template code works for singly tagged items, but fails for items with multiple tags:
<a href='/view.php?mode=list&filter=[[Tags]]'>[[Tags]]</a>
Is there a way to loop over items in a multi-select? Something like:
[[for Tag in Tags]] <a href='/view.php?mode=list&filter=[[Tag]]'>[[Tag]]</a> [[/for]]
I'm not certain there is an easy way to do this using the method above. Though, I've hacked together some javascript to accomplish the same thing:
function init() {
var tags = document.getElementsByClassName('tags');
for (var i=0; i<tags.length; i++) {
tags[i].innerHTML = tags[i].innerHTML.replace(/\w[\w\s]+?(?=<br>)/g, function(n) {
return "<a href='view.php?d=16&mode=list&perpage=10&filter=1&f_81%5B%5D="+ escape(n) + "'>" + n + "</a>";
});
}
};
window.onload = init;
Assuming you have an edit_form.php with something like this
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/formslib.php');
class edit_form extends moodleform {
public function definition() {
$mform =& $this->_form;
$options = array('red' => 'red', 'blue' => 'blue', 'green' => 'green');
$select = $mform->addElement('select', 'tags', get_string('tags'), $options);
$select->setMultiple(true);
$this->add_action_buttons(false, get_string('submit'));
}
}
Then use this in your edit.php file
require_once(dirname(__FILE__) . '/edit_form.php');
...
$mform = new edit_form();
$mform->display();
if ($formdata = $mform->get_data()) {
foreach ($formdata->tags as $tag) {
$url = new moodle_url('/view.php', array('mode' => 'list', 'tag' => $tag));
echo html_writer::link($url, $tag);
}
}

TYPO3-6.2 Extbase custom content type -> invalid value

I made an extbase Extension for custom content elements. Since this is my first extension I started with a simple "hello_world_ce". This are my files:
ext_tables.php
<?php
$TCA['tt_content']['types']['hello_world_ce']['showitem'] = '--palette--;LLL:EXT:hello_world/Resources/Private/Language/locallang_mod.xlf:content_element.hello_world.general;general, --palette--;LLL:EXT:hello_world/Resources/Private/Language/locallang_mod.xlf:content_element.hello_world.header;header';
ext_localconf.php
<?php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('<INCLUDE_TYPOSCRIPT: source="FILE:EXT:'.$_EXTKEY.'/Configuration/TypoScript/ModWizards.ts">');
ModWizards.ts
mod.wizards {
newContentElement {
wizardItems {
hello_world {
header = LLL:EXT:hello_world/Resources/Private/Language/locallang_mod.xlf:content_tab_header
elements {
hello_world_ce {
icon = gfx/c_wiz/regular_header.gif
title = LLL:EXT:hello_world/Resources/Private/Language/locallang_mod.xlf:content_element.hello_world
description = LLL:EXT:hello_world/Resources/Private/Language/locallang_mod.xlf:content_element.hello_world.description
tt_content_defValues {
CType = hello_world_ce
}
}
}
}
show = *
}
}
}
In the TYPO3 Backend I see my content element and can add it to a page but the dropdown menu for the content type says INVALID VALUE ("hello_world_ce")
What am I missing?
EDIT: I found the missing part. I needed to add my content type to the CType array
ext_tables.php
$backupCTypeItems = $GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items'];
$GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items'] = array(
array(
'LLL:EXT:'.$_EXTKEY.'/Resources/Private/Language/locallang_mod.xlf:content_tab_header',
'--div--'
),
array(
'LLL:EXT:'.$_EXTKEY.'/Resources/Private/Language/locallang_mod.xlf:content_element.hello_world',
'hello_world_ce',
'i/tt_content_header.gif'
)
);
foreach($backupCTypeItems as $key => $value){
$GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items'][] = $value;
}
The question was edited, but I think there is a better way to achieve the solution.
Only to be clear about the problem:
The content element hello_world_ce was not added to the "types" dropdown by adding a new content element.
The hint in the question is correct it was not defined for the CType field.
But instead of manipulating the array you could use a core function:
// Adds the content element to the "Type" dropdown
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(
array(
'LLL:EXT:your_extension_key/Resources/Private/Language/locallang_mod.xlf:content_element.hello_world',
'hello_world_ce',
'i/tt_content_header.gif'
),
'CType',
'your_extension_key'
);
Here is a very good example of how to add your own content element in the version TYPO3 7.6.
Note: This function is accessible in TYPO3 6.2 as well.

Laravel: Multiple File Upload, Input::hasFile(key) always false

i generated a multiple upload form with the former generator tool from https://github.com/Anahkiasen/former.
{{ Former::files('file')->accept('image')->required(); }}
that results in
<input multiple="true" accept="image/*" required="true" id="file[]" type="file" name="file[]">
After I've submit the form Ive figured out that Input::hasFile('file') always returns false whilst Input:has('file') returns true.
What i've tried until now:
Log::info(Input::file('file')); <-- empty
foreach(Input::file('file') as $file) <-- Invalid argument supplied for foreach()
Log::info("test");
if(Input::has('file'))
{
if(is_array(Input::get('file')))
foreach ( Input::get('file') as $file)
{
Log::info($file); <-- returns the filename
$validator = Validator::make( array('file' => $file), array('file' => 'required|image'));
if($validator->fails()) {
...
}
}
}
Of course, the validator always fails cause Input::get('file') does not return a file object. How do I have to modify my code to catch the submited files?
Thanks for the help, the answer from Kestutis made it clear. The common way to define a file form in Laravel is
echo Form::open(array('url' => 'foo/bar', 'files' => true))
This Options sets the proper encryption type with enctype='multipart/form-data'.
With the laravel form builder "Former" you have to open the form with
Former::open_for_files()
After that u can validate the form in the common way.
if(Input::hasFile('files')) {
Log::info(Input::File('files'));
$rules = array(
...
);
if(!array(Input::File('files')))
$rules["files"] = 'required|image';
else
for($i=0;$i<count(Input::File('files'));$i++) {
$rules["files.$i"] = 'required|image';
}
$validation = Validator::make(Input::all(), $rules);
if ($validation->fails())
{
return ...
}
else {
// everything is ok ...
}