TYPO3: clear cache by tag for custom content element when record in backend is changed - typo3

I have a sysfolder with records which get displayed in the frontend via a custom content element.
Now I have the problem that the frontend is not updated when a new record is added or an existing record is changed.
To clear the cache I'm using a hook in ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc']['foobar'] =
\Vendor\Name\Hooks\DataHandler::class . '->clearCachePostProc';
The hook looks like this:
<?php
namespace Vendor\Name\Hooks;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class DataHandler implements SingletonInterface
{
public function clearCachePostProc(array $params): void
{
if (isset($params['table']) && $params['table'] === 'tx_foo_domain_model_bar') {
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
$cacheManager->flushCachesByTag('1642782027');
}
}
}
And the content element is implemented with FLUIDTEMPLATE and a dataprocessor:
tt_content {
foo_bar =< lib.contentElement
foo_bar {
templateName = myTemplate
stdWrap.cache {
key = tx_foo_domain_model_bar
tags = 1642782027
lifetime = default
}
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
table = tx_foo_domain_model_bar
pidInList = {$foo.storage_pid}
as = foobar
}
}
}
}
Everything seems to work but when I hit Cmd+R/Ctrl+R and reload the page or visit it again via the navigation, the page is not updated with the latest content.

I implemented the following solution.
Within the Typoscript Setup add a addPageCacheTag to your custom content element:
tt_content {
foo_bar =< lib.contentElement
foo_bar {
templateName = FooBar
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
table = tx_foo_domain_model_bar
pidInList = {$foo.storage_pid}
as = foobar
}
}
stdWrap.addPageCacheTags = foo_bar
}
}
Add the clearCacheCmd to the Page TSConfig from the storage page like:
TCEMAIN.clearCacheCmd = cacheTag:foo_bar
For testing, add this to your Fluid-Template and be sure to test with a separate browser (without BE login):
<div style="color: red;"><f:format.date format="d.m.Y - H:i:s">now</f:format.date></div>
Kudos to https://daniel-siepmann.de/posts/2019/typo3-content-caching.html

You could use the EXT:Fluid Page Cache
https://extensions.typo3.org/extension/fluid_page_cache
This EXT does all the things you need automatically.

Related

TYPO3 11 set custom page title h1 html

I have TYPO3 11.
I created a Page Title Provider
<?php
declare(strict_types=1);
namespace Myvendor\modellobando\Seo;
use TYPO3\CMS\Core\PageTitle\AbstractPageTitleProvider;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class BandoTitleProvider extends AbstractPageTitleProvider
{
private const DEFAULT_PROPERTIES = 'title';
private const DEFAULT_GLUE = '" "';
public function setTitle(string $title): void
{
$this->title = "ecco ".$title;
}
}
I defined it in template.setup
config.pageTitleProviders {
record {
provider = Goproject\modellobando\Seo\BandoTitleProvider
}
}
It works with meta tag title but the data of the page is not changed, I have to set the tag h1 in html in my layout, how can I do that?
updated question:
As I wrote in comment I tried a query to get info about my model but I don't know how avoid SQL injection using query string parameter (GET) like uid=12
page.10 {
dataProcessing {
1001 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
1001 {
table=mytable
pidInList = 16
markers.uid.field = uid
as = datainfobando
where = (uid = ???)
}
}
}
Using a h1 tag means you are in the body of the HTML document. That content does not have an automated content.
But you can insert it in your page template. If you want it set everywhere you can use the page layout template. You only have to provide the information to your FLUID page template, which can be done easily in typoscript.
Avoiding SQL-injection within a select can be done with using markers and securing them.
Eg. reducing them to integer values.
1001 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
1001 {
table=mytable
pidInList = 16
where = {#uid} = ###recordId###
as = datainfobando
markers {
recordId.data = GP:myId
recordId.intval = 1
}
}

Typo3 10.4.4 Gridelements 10.0.0 extension not working

Hey I am pretty new to typo3 and I want to build a website.
I am running version 10.4.4 of TYPO3 with the bootstrap package installed.
I have tried to follow the guide on https://docs.typo3.org/typo3cms/extensions/gridelements/stable/
I have copied the TypoScript into my template setup, but there is no output on the frontend.
Remember I am new to this so I don't understand the TypoScript well yet.
So any ideas to what I could do?
EDIT:
I want to use GriElements so that I can create my own layouts on my page. The standard layouts are good but I need more freedom than what they offer.
I can get output on the frontend without GridElements, but when I use the extension only the content in the GridElements block wont show. If I remove the standard TypoScript from the example on the manual page for this extension i get an error saying "Oops an error occurred! Code:" and then a code that changes every time I update the page.
My TypoScript on my template looks like this:
page.includeCSS.1 = fileadmin/user_upload/template/css/fonts.css
page.includeCSS.theme = fileadmin/user_upload/template/css/custom-theme.scss
# plugin.tx_bootstrappackage._LOCAL_LANG.da.readmore = test (NOT WORKING)
# https://docs.typo3.org/m/typo3/reference-coreapi/10.4/en-us/ApiOverview/Internationalization/ManagingTranslations.html
page.meta.robots = noindex, nofollow
page.meta.robots.replace = 1
page.10.partialRootPaths.3 = fileadmin/user_upload/template/partials/ContentElements/
page.10.partialRootPaths.4 = fileadmin/user_upload/template/Partials/Page/
page.10.dataProcessing.10.levels = 3
page.includeJSFooterlibs.bootstrap_navbar = fileadmin/user_upload/template/js
page.includeJSFooterlibs.bootstrap_navbar = fileadmin/user_upload/template/js/navbar.js
lib.contentElement.partialRootPaths.20 = fileadmin/user_upload/template/partials/ContentElements/
lib.contentElement.partialRootPaths.20 = fileadmin/user_upload/template/Partials/ContentElements/
lib.gridelements.defaultGridSetup {
// stdWrap functions being applied to each element
columns {
default {
renderObj = COA
renderObj {
# You can use registers to i.e. provide different image settings for each column
# 10 = LOAD_REGISTER
20 =< tt_content
# And you can reset the register later on
# 30 = RESTORE_REGISTER
}
}
}
# if you want to provide your own templating, just insert a cObject here
# this will prevent the collected content from being rendered directly
# i.e. cObject = TEMPLATE or cObject = FLUIDTEMPLATE will be available from the core
# the content will be available via fieldnames like
# tx_gridelements_view_columns (an array containing each column)
# or tx_gridelements_view_children (an array containing each child)
# tx_gridelements_view_column_123 (123 is the number of the column)
# or tx_gridelements_view_child_123 (123 is the UID of the child)
}
lib.tt_content.shortcut.pages = COA
lib.tt_content.shortcut.pages {
10 = USER
10 {
userFunc = tx_gridelements_view->user_getTreeList
}
20 = CONTENT
20 {
table = tt_content
select {
pidInList.data = register:pidInList
where = colPos >= 0
orderBy = colPos,sorting
orderBy.dataWrap = FIND_IN_SET(pid,'{register:pidInList}'),|
}
}
}
tt_content.shortcut.5 = LOAD_REGISTER
tt_content.shortcut.5 {
tt_content_shortcut_recursive.field = recursive
}
tt_content.shortcut.20 {
0 {
tables := addToList(pages)
conf.pages < lib.tt_content.shortcut.pages
}
1 {
tables := addToList(pages)
conf.pages < lib.tt_content.shortcut.pages
}
}
tt_content.gridelements_pi1 >
tt_content.gridelements_pi1 = COA
tt_content.gridelements_pi1 {
#10 =< lib.stdheader
20 = COA
20 {
10 = USER
10 {
userFunc = tx_gridelements_view->main
setup {
default < lib.gridelements.defaultGridSetup
}
}
}
}
The statics i included is:
Bootstrap Package: Full Pacakage (bootstrap_package)
Bootstrap Package: Bootstrap 4.x (SCSS) (bootstrap_package)
XML Sitemap (seo)
Gridelements w/DataProssing (recommended) (gridelements)
Gallery (bm_image_gallery)
EDIT2:
New TypoScript with DataProcessing
lib.gridelements.defaultGridSetup =< lib.contentElement
lib.gridelements.defaultGridSetup {
templateName.field = tx_gridelements_backend_layout
templateName.ifEmpty = GridElement
layoutRootPaths {
1 = EXT:gridelements/Resources/Private/Layouts/
}
partialRootPaths {
1 = EXT:gridelements/Resources/Private/Partials/
}
templateRootPaths {
1 = EXT:gridelements/Resources/Private/Templates/
}
dataProcessing {
10 = GridElementsTeam\Gridelements\DataProcessing\GridChildrenProcessor
10 {
default {
as = children
# Default options of the grid children processor
# Change them according to the needs of your layout
# Read more about it in the TypoScript section of the manual
# options {
# sortingDirection = ASC
# sortingField = sorting
# recursive = 0
# resolveFlexFormData = 1
# resolveBackendLayout = 1
# respectColumns = 1
# respectRows = 1
# }
}
}
}
}
My includes:
Fluid Contetn Elements (fluid_styled_content)
Fluid Contetn Elements CSS (fluid_styled_content)
Bootstrap Package: Full Pacakage (bootstrap_package)
Bootstrap Package: Bootstrap 4.x (SCSS) (bootstrap_package)
XML Sitemap (seo)
Gridelements w/DataProssing (recommended) (gridelements)
Gallery (bm_image_gallery)
The error I get:
Tried resolving a template file for controller action "Standard->3" in format ".html", but none of the paths contained the expected template file (Standard/3.html). The following paths were checked: /httpdocs/typo3conf/ext/bootstrap_package/Resources/Private/Templates/ContentElements/, /httpdocs/typo3conf/ext/gridelements/Resources/Private/Templates/
You probably missed to include the static template of gridelemnts. To do so edit your TS-Root-Template, select in the dropdown at the top "Info/Modify", hit the button "Edit the whole template record", go to tab "Includes" and select gridelements static setup in the Multiselect box on the right.
Please provide more information:
Which static templates have you included at all? Maybe you forgot to include fluid_styled_content?
How does your Typoscript/Flexform setup look like?
For what do you need gridelements?
EDIT: bootstrap_package did not very well together with gridelements in the past. Maybe you should first try to install Benjamin Knott's extension autogrids (see this issue on github for more information)
EDIT 2: Try this Typoscript, it just wraps a section around all elements but maybe you will then see your content in the frontend:
tt_content.gridelements_pi1.20.10.setup {
section < lib.gridelements.defaultGridSetup
section {
wrap >
dataWrap = <section id="c{field:uid}">|</section>
}
}
SOLVED:
I installed an extension that is called "Grids for bootstrap" included it in the template and it worked.
Thnaks for all the help you guys gave!
I think your problem is coming from your fluid code for gridelemnts, you didn't use the right syntax maybe.

Overriding fluid_styled_content isn't working as expected

Hei guys,
I've been trying really hard to override the templates, partials, and headers of some default content elements from fluid_styled_content.
For instance, lets say 'Header'.
I also have a data processing class to fetch certain fields from tt_content table to process inside the header.
Anyhow, I can receive this fetched data inside the template. But not in the partials or layouts.
Did anyone ever faced the same?
This was my TS setup :
lib.contentElement {
templateRootPaths {
200 = EXT:my_ext/Resources/Private/Templates/
}
partialRootPaths {
200 = EXT:my_ext/Resources/Private/Partials/
}
layoutRootPaths {
200 = EXT:my_ext/Resources/Private/Layouts/
}
}
//custom content element definition
tt_content {
header < lib.contentElement
header {
templateName = Header
dataProcessing {
1 = VENDOR\MyExt\DataProcessing\ContentProcessor
}
}
}
I assume it's about the order of your typoscript.
in your example you have the code
tt_content {
header < lib.contentElement
:
which copies the lib.contentElement object. it copies the object in that state it has in the moment when the copy operator is detected. any following changes will not be included.
If you want to build a reference, where you can change the referenced ('copied') object afterwards and all those changes should be active too you need to use the reference operator:
tt_content {
header =< lib.contentElement
:

Access page properties within fluid_styled_content element

I'm trying to extend the fluid_styled_content element "Menu". Within my partial (e.g. typo3conf/ext/my_theme/Resources/Private/Templates/Content/Partials/Menu/Type-1.html I need to access the page properties of the page where the menu CE resides. How can I archive this? {data} contains only the data of the content element.
In {data.pid} you have the uid of the page.
You can use a viewhelper to get the complete pages record (in ext:vhs there is a viewhelper to get any kind of records).
or you can use <f:cObject> and some typoscript to access single values.
Use \TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor.
I cannot check the code right now but you could take this as a starting point:
tt_content.menu.dataProcessing {
30 = \TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
30 {
table = pages
where.dataWrap = uid = {TSFE:id}
as = page
}
}
Afterwards you can access the current page‘s properties via {page.0.property}.
There‘s just one query for each menu content object with this approach while most view helper solutions tend to increase the number of database queries issued.
#undko: The DatabaseQueryProcessor was the perfect hint. But your snippet had two problems I had to fix:
- the TypoScript code needs pidInList to work
- in the Fluid Template there was data missing: pageproperties.0.data.myproperty
Here is my final code that works fine for me:
tt_content.menu.dataProcessing {
30 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
30 {
table = pages
where.dataWrap = uid = {TSFE:id}
pidInList = 1
as = pageproperties
}
}
In the Fluid template I use {pageproperties.0.data.tx_mytheme_fieldname}.
I don't know why exactly but I can't access page properties with the proposed solution. I'm using Typo3 10.4.9.
I found an alternative solution :
tt_content.menu dataProcessing {
30 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
30 {
table = pages
pidInList = 0
recursive = 99
uidInList = this
as = pageproperties
}
}
Maybe this will help someone else.
More brutal approach; to access the page properties everywhere, for example in a custom content element. Create in the sitepackage Classes/ViewHelper/GetPagePropertiesViewHelper.php :
<?php namespace Xxx\Sitepackage\ViewHelpers;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class GetPagePropertiesViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper
{
public function initializeArguments()
{
$this->registerArgument('pid', 'int', 'The page uid to get the pageproperties from', true, 1);
$this->registerArgument('property', 'string', 'A specific page property to be returned', false, null);
}
public function render()
{
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('pages');
$pageProperties = [];
$statement = $queryBuilder
->select('*')
->from('pages')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($this->arguments['pid'], \PDO::PARAM_INT))
)
->execute();
while ($row = $statement->fetch()) {
$pageProperties[] = $row;
}
if ($property) {
return $pageProperties[0][$property];
}
return $pageProperties[0];
}
}
Usage in a template or partial:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:c="http://typo3.org/ns/Xxx/Sitepackage/ViewHelpers"
data-namespace-typo3-fluid="true">
<c:getPageProperties pid="{data.pid}" property="description"/>
<f:debug><c:getPageProperties pid="{data.pid}"/></f:debug>

Get FlexForm configuration in TypoScript

I need to get the page.headerData in typoscript from pi_flexform.How can implement my requirement?
page = PAGE
page {
headerData {
10 = TEXT
10.value =<script>/**********************/</script>
}
}
I am not so sure about what you really need. I am guessing you want to access a FlexForm configuration inside your TypoScript?
Since the version 8.4 this is possible by using plain TypoScript
lib.flexformContent = CONTENT
lib.flexformContent {
table = tt_content
select {
pidInList = this
}
renderObj = COA
renderObj {
10 = TEXT
10 {
data = flexform: pi_flexform:settings.categories
}
}
}
The key flexform is followed by the field which holds the flexform data and the name of the property whose content should be retrieved.
Before 8.4 you need to use a userFunc and retrieve the value by using PHP
$flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
$flexFormKey = str_replace('.', '|', $keyParts[1]);
$settings = $flexFormService->convertFlexFormContentToArray($flexFormContent);