TYPO3 : How to create a header image that will be inherited by sub pages - typo3

I have to set up a TypoScript-configuration for a header image with the following requirements:
The editor should be able to define a header image for a page using the "edit page-properties->resources->media" dialogue. If a page doesn`t have a header image, the parent pages should be scanned for header images and the first header image found on the way up to the page-tree root should be used.
Editors should also be able to add content elements to a certain "Page Header" section. This content elements can either be slider/menus or images. If a content element of the type "image" or "text with image" is added, only the image itself and no other additional code should be rendered. The content elements added to the page-header section should have priority. So if a page contains a content element in the page-header section and also has an image in the resources->media field, the image from the media-field of that page or any other page on a higher level in the page tree will be ignored and the content element/image from the page-header section will be rendered.
Fallback: if there is no content in the page-header section and also no images can be found in the media field of the page or other pages in it`s rootline, a default image which is defined via a TypoScript constant should be rendered to prevent that the header section will be left empty.

This TypoScript uses override, slide and a nested COA object to render a header image in a way that meets the given requirements:
lib.fallBackHeaderImage = IMAGE
lib.fallBackHeaderImage {
file {
import.cObject = TEXT
import.cObject.value = {$portal.context.headerImage.filename}
maxW = 1124
maxH = 342
}
}
lib.headerImage = IMAGE
lib.headerImage {
file {
import {
data = levelmedia:-1, slide
listNum = 0
}
treatIdAsReference = 1
maxW = 1124
maxH = 342
}
}
lib.headerContent < styles.content.getLeft
lib.headerContent {
renderObj < tt_content
renderObj {
image >
image = FILES
image {
references {
table = tt_content
fieldName = image
uid.data = uid
}
renderObj = IMAGE
renderObj {
file {
import.data = file:current:originalUid // file:current:uid
maxW = 1124
maxH = 342
}
}
}
textpic >
textpic < .image
}
}
lib.pageHeader = COA
lib.pageHeader {
// 10 reserved for prepend content
20 = COA
20 {
10 = COA
10 {
10 < lib.fallBackHeaderImage
stdWrap {
override {
required = 1
cObject < lib.headerImage
}
}
}
stdWrap {
override {
required = 1
cObject < lib.headerContent
}
}
}
// 30 reserved for appended content
}

Related

TYPO3 10 <f:cObject/> does NOT render first content-element from tt_content table after clearing cache

I am currently facing the issue, that when I fetch content from a specific page via typoscript, I only get the full content after the second pageload if I have deleted all caches before. The first content element is not rendered at all (seems to be ignored).
Here is my Typoscript:
lib.dynamicContent = COA
lib.dynamicContent {
5 = LOAD_REGISTER
5 {
colPos.cObject = TEXT
colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
pageUid.cObject = TEXT
pageUid.cObject {
field = pageUid
ifEmpty.data = TSFE:id
}
contentFromPid.cObject = TEXT
contentFromPid.cObject {
data = DB:pages:{register:pageUid}:content_from_pid
data.insertData = 1
}
wrap.cObject = TEXT
wrap.cObject {
field = wrap
}
}
20 = CONTENT
20 {
table = tt_content
select {
includeRecordsWithoutDefaultTranslation = 1
orderBy = sorting
where = {#colPos}={register:colPos}
where.insertData = 1
pidInList.data = register:pageUid
pidInList.override.data = register:contentFromPid
}
stdWrap {
dataWrap = {register:wrap}
required = 1
}
}
90 = RESTORE_REGISTER
}
This is how I render the content in fluid:
<f:cObject typoscriptObjectPath="lib.dynamicContent" data="{pageUid: '41', colPos: '1'}" />
The output from the first content element after clearing the cache is on the first pageload: <div />. When I reload the page, I get the full content from the page.
I already checked the database queries which are executed, but they are always the same and return the correct results.
System:
TYPO3 10.4.8
PHP 7.3
You should remove the stdWrap part, which contains a wrap, that should be created via plain HTML in your Fluid template instead.
Im not 100% sure, but I guess the required check within that stdWrap section disables the content as well, since it might be checked before the actual content has been rendered.

Use cropped image with fallback in TypoScript in TYPO3 8

This TS code always produces a 600x400px image:
10 = FILES
10 {
required = 1
references {
table = tt_content
fieldName = image
}
renderObj = IMAGE
renderObj {
wrap = <div class="teaser-image">|</div>
file.import.data = file:current:originalUid // file:current:uid
file.crop.data = file:current:crop
file.width=600c
file.height=400c
}
}
If I remove
file.width=600c
file.height=400c
then the cropped image from the crop wizard will be used.
But I need both (it's an upgrade of an existing site): if available, the cropped image is used, but if not, the given height and width are used.
How do I use the "file:current:crop" part to override width & height only if given? Or how do I set a fallback? something like...
file.crop.data = file:current:crop // fallback...
I've moved to FLUIDTEMPLATE in the renderObj:
renderObj = FLUIDTEMPLATE
renderObj {
file = path/to/templates/content/teaser.html
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
10 {
references.fieldName = image
references.table = tt_content
as = teaserimages
}
}
}
(The FilesProcessor is required)
And then in the template
<img src="<f:uri.image image="{teaserimages.0}" width="600c" height="400c" />
Behaves as expected

TYPO3 Menu Double up

I have this custom menu setup based on the default section menu. When testing on one content element, it looks good... When I add a second content element to the page both get added to each menu item.
Anyone know what's going on here?
tt_content.menu.20.3.1.sectionIndex.useColPos = -1
tt_content.menu.20.101 < tt_content.menu.20.3
tt_content.menu.20.101 {
1.NO {
stdWrap.cObject = CONTENT
stdWrap.cObject {
table = tt_content
select {
pidInList.field = uid
}
renderObj = COA
renderObj {
10 = FILES
10 {
stdWrap.wrap = <div class="menu-img">|</div>
references {
table = tt_content
fieldName = image
}
renderObj = IMAGE
renderObj {
file {
import.data = file:current:uid
treatIdAsReference = 1
width = 100c
height = 100c
}
altText.data = file:current:alternative
titleText.data = file:current:title
stdWrap.typolink.parameter.data = file:current:link
}
maxItems = 1
}
20 = TEXT
20.field = header
30 = TEXT
30.field = rowDescription
}
}
}
}
This is currently outputting:
<ul>
<li><img/>Heading1Desc1<img2/>Heading2Desc2</li>
<li><img/>Heading1Desc1<img2/>Heading2Desc2</li>
<ul>
What it should be:
<ul>
<li><img/>Heading1Desc1</li>
<li><img2/>Heading2Desc2</li>
</ul>
It is about your CONTENT object.
your selection is strange:
select {
pidInList.field = uid
}
you select all tt_content elements which are in the page with the uid of the current content element.
And your rendering is executed for each record found.
Do you really need to select the contentelement with a cObject again? I think in the menu it should be the current context.
add on:
I would try something like this to render the image before the text (which should be available by default):
before just for the image instead of stdWrap with a full query of all CEs and with a COA for all fields.
have a look to the correct fieldname!
1.NO {
before.cObject = FILES
before.cObject {
stdWrap.wrap = <div class="pic">|</div>
references {
table = tt_content
uid.data = uid
// 'image' or 'media' or ... ???
fieldName = image
}
renderObj = IMAGE
renderObj {
stdWrap.wrap = <div class="pic">|</div>
file {
import.data = file:current:uid
treatIdAsReference = 1
width = 150c
height = 150c
}
altText.data = file:current:alternative
titleText.data = file:current:title
#params = class="menu-img"
// don't do a link inside a link =:-O
#stdWrap.typolink.parameter.data = file:current:link
}
maxItems = 1
}
}
I have tried this many different ways and cannot get it working with the image and fields. So instead I have simply patched my original code using by adding: tt_content.menu.20.101.maxItems = 1 and adding a wrap to the renderObj.
I know this is not how it should be done, but it works for now. But if anyone knows the correct way of doing it let me know!

Typoscript menu image size

In my menu I am using a script to retrieve the image loaded in the page's resources.
Now I need to make it so the image is resized/cropped to exactly the right size. Where can I add the width and height to make it work?
NO {
wrapItemAndSub = <li>|</li>
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10.field = title
10.wrap = <span>|</span>
20 = FILES
20 {
# Get the images related to the current page
references {
table = pages
fieldName = media
}
# Render each image and wrap it as appropriate
renderObj = TEXT
renderObj {
typolink {
parameter.data = file:current:publicUrl
forceAbsoluteUrl = 1
returnLast = url
}
wrap = |,
}
stdWrap {
# Take only the first image if several are defined
listNum = 0
# Use default image if none is available
ifEmpty.cObject = TEXT
ifEmpty.cObject.typolink {
parameter = fileadmin/templates/example/images/placeholder.png
forceAbsoluteUrl = 1
returnLast = url
}
wrap = <div><img src="|" /></div>
}
}
}
}
If you want to resize the image replace the renderObj = TEXT through renderObj = IMG_RESOURCE
Example:
NO {
wrapItemAndSub = <li>|</li>
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10.field = title
10.wrap = <span>|</span>
20 = FILES
20 {
# Get the images related to the current page
references {
table = pages
fieldName = media
}
# Render each image and wrap it as appropriate
renderObj = IMG_RESOURCE
renderObj {
file.import.data = file:current:uid
file.treatIdAsReference = 1
file.width = 250c
file.height = 250c
wrap = |,
}
stdWrap {
# Take only the first image if several are defined
listNum = 0
# Use default image if none is available
ifEmpty.cObject = TEXT
ifEmpty.cObject.typolink {
parameter = fileadmin/templates/example/images/placeholder.png
forceAbsoluteUrl = 1
returnLast = url
}
wrap = <div><img src="|" /></div>
}
}
}
To render only one image, you shouldn't make first an list of all images. Use the maxItems setting of FILES and remove the listNum from stdWrap.
20 = FILES
20 {
...
maxItems = 1
...
}
I think you need to use GIFBUILDER.
The GIFBUILDER will pass the Image to for example ImageMagick and will help you to cut/scrop/scale the image to your needs.
Something like
lib.image = IMAGE
lib.image {
file = GIFBUILDER
file {
#use the c in XY to crop
XY = 1024c,768c
format = jpg
10 = IMAGE
10.file = fileadmin/image.jpg
}
}
You can read more about Gifbuilder here:
https://docs.typo3.org/typo3cms/TyposcriptReference/Gifbuilder/Index.html

typoscript renderObj image problem

i dont figure out how i can render an image into my renderObj COA.
Here my code:
renderObj = COA
renderObj {
10 = TEXT
10.field = header
10.parseFunc < lib.parseFunc_RTE
10.wrap = <h2>|</h2>
20 = TEXT
20.field = bodytext
20.parseFunc < lib.parseFunc_RTE
30 = IMAGE
???
30.parseFunc < lib.parseFunc_RTE
}
As you can see i typed only three questionmarks as placeholder.
Please help me :(
Depending on where you get the image from, here are some examples.
renderObj = COA
renderObj {
# Static image
10 = IMAGE
10.file = fileadmin/user_upload/images/myPicture.jpg
# From a database field
20 = IMAGE
20.file.import = uploads/pics/
20.file.import {
field = image
listNum = 0
}
}
There is no need to assign lib.parseFunc_RTE to the image, since that's only valid for RTE content.
See the official documentation, TSref, for more details on IMAGE ande imgResource.
IMAGE: http://typo3.org/documentation/document-library/references/doc_core_tsref/4.4.0/view/1/7/#id2632631
imgResource: http://typo3.org/documentation/document-library/references/doc_core_tsref/4.4.0/view/1/5/#id2619917