Output nested tags with one single ViewHelper - typo3

I have a TYPO3 project with an extension using Extbase and to implement lazy loading and retina images while maintaining compatibility if javascript is disabled, I need to generate some output like this:
<noscript data-src-small="small.jpg" data-src-large="large.jpg" data-width="300" data-height="200">
<img src="small.jpg" width="300" height="200">
</noscript>
So I wrote a custom ViewHelper (or rather I copied and modified an existing one) that does exactly this and it works, but I'm not sure I'm doing it right, because I'm manually creating the <img> like this:
$content = '<img class="'.$class.'" alt=" " src="'.$imageSource.'" width="'.$imageInfo[0].'" height="'.$imageInfo[1].'">';
$this->tag->setContent($content);
I wonder if there isn't a better way to do this, ideally I'd like to call the standard ImageViewHelper::render() function inside my custom ViewHelper.
Is there any way to do that? Should that even be done at all?
I am aware, I could adjust my template like this:
<x:noscript src="filename.jpg" width="300">
<f:image src="filename.jpg" width="300" />
</x:noscript>
(x:noscriptis supposed to be my custom ViewHelper)
and call renderChildren() inside my ViewHelper.
But then I would have to repeat src="filename.jpg" width="300" and I generally don't like to repeat input if there's a better way.

The easiest way to achieve what you want is to use a partial. It would look like this:
{namespace x=Yourcompany\Yourproduct\ViewHelpers}
<f:comment>
Parameters:
* src: src of the image
* width: Width of the image
</f:comment>
<x:noscript src="{src}" width="{width}">
<f:image src="{src}" width="{width}" />
</x:noscript>
You can use it like this:
<f:render
partial="Path/To/Partial"
arguments="{width: 300, src: 'filename.jpg'}
/>

Related

How to use usage of Appearnce tab of Mask CE in TYPO3?

When adding Mask content element it doesn't reflect some setting of the Appearance tab at front-end, like Layout, Frame, Space Before or After, also it doesn't include the uid of content element. How can I make usage of these fields?
By default Mask elements do not use standard wrapping for rendering the content element, fortunately you can easily access them within data variable which contains array of tt_content.
To check what fields of tt_content are available just put the line in FE template of your Mask element:
<f:debug>{data}</f:debug>
So you can make the wrapper div by yourself using simple Fluid syntax
<div class="
{f:if(condition: data.layout, then: 'frame-layout-{data.layout}')}
{f:if(condition: data.frame_class, then: 'frame-{data.frame_class}')}
{f:if(condition: data.space_before_class, then: 'frame-space-before-{data.space_before_class}')}
{f:if(condition: data.space_after_class, then: 'frame-space-after-{data.space_after_class}')} ">
<!-- your markup here -->
</div>
You can use the layouts like fluid_styled_content does - it takes care of headers, frames, spaceBefore, etc. This is also the easiest way.
First step: define the layout directories in TypoScript:
lib.maskContentElement.layoutRootPaths.5 = EXT:fluid_styled_content/Resources/Private/Layouts/
lib.maskContentElement.partialRootPaths.5 = EXT:fluid_styled_content/Resources/Private/Partials/
Second step: use the layout in your template:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="Main">
<!-- your markup here -->
</f:section>
</html>
This also works for DCE (with corresponding TypoScript path)
Of course you can copy the layouts and partials to your theme path and make changes there, but I recommend sticking to the core functionality.

TYPO3 FLUID STYLED CONTENT with Lazy Load Javascript Plugin

Unfortunately I'm still using TYPO3 7.6, but it's the same in principle like the latest TYPO3 CMS, so I also use Fluid_styled_content .. uff!
I've included the lazy load javascript plugin into my TYPO3-Website and now I try to change the FLUID-partial typo3conf/ext/myext/Resources/Private/Extensions/Fsc/Partials/MediaGallery.html - but I've a probem with this .. because my changing in line 'file' throws an error. I try it with or without " or \" ..
<f:section name="media">
<f:media
file="{f:uri.image(src: \"EXT:/myext/Resources/Public/img/icons/blank.gif\", treatIdAsReference:1}"
class="lazyload"
data="{src: '{f:uri.image(image: column.media)}'}"
width="{column.dimensions.width}"
height="{column.dimensions.height}"
alt="{column.media.alternative}"
title="{column.media.title}"
/>
</f:section>
I've changed file="{column.media}" , because I want to load my 'blank.gif' instead of the image himself.
Argument 1 passed to TYPO3\CMS\Core\Resource\Rendering\RendererRegistry::getRenderer() must implement interface TYPO3\CMS\Core\Resource\FileInterface, string given, called in C:\www\typo3_src-7.6.31\typo3\sysext\fluid\Classes\ViewHelpers\MediaViewHelper.php on line 90
The output is like this:
<img data-src="/fileadmin/user_upload/admins.jpg" class="lazyload" src="/fileadmin/user_upload/admins.jpg" width="280" height="176" alt="">
Lazy load is working perfect, but I have to load the blank.gif.
Is there a solution to manipulate the FSC-partials or do I need a new ViewHelper, like this?

TYPO3 fluid f:image without width/height attribute / f:uri.image issues

I'm having some trouble getting {f:uri.image} to work, this doesn't render:
<img src="{f:uri.image(src:person.firstImage,treatIdAsReference:1, width:150c,height:150c,cropVariant:'square')}"/>
person.firstImage is of type TYPO3\CMS\Extbase\Domain\Model\FileReference.
Maybe you spot the error?
On the other hand, this works:
<f:image class="image-author" image="{person.firstImage}" width="150c" height="150c" cropVariant="square"/>
... but then the output will always feature the width="150" height="150" html attributes, which will conflict with responsive CSS.
Is there a way to prevent f:image from outputting with and height in the source tag? Probably not, if I look at the VH?
You need to escape the width and height when adding c
<img src="{f:uri.image(src:person.firstImage,treatIdAsReference:1, width:'150c',height:'150c',cropVariant:'square')}"/>
Would also go for:
<img src="{f:uri.image(image:person.firstImage,width:'150c',height:'150c',cropVariant:'square')}"/>

TYPO3 <f:image /> nest viewhelper or use the processed image somehow for lazyload

I'm trying to imply lazyload with a specific slider, it requests the src of the image to be entered twice, once as src and second as data-lazy like this:
<img src="domain.com/image.png" data-lazy="domain.com/image.png">
with <f:image /> I can use data="{lazy: 'domain.com/image.png'}" and should repeat the src of the image created with the viewhelper ... (typo3 documentation and the inline use of f:uri.image)
i have actually two questions:
how do I nest f:uri.image ? this gives an error <f:image src="{image.uid}" treatIdAsReference="1" data="{lazy: '{f:uri.image(src: {image.uid})}'}"/>
it should actually be the refference to the same
image, if I nest f:uri.image would I create a second rendered image ?
(especially because I also set width and height, but I wanted to keep the snippets simple)
the solution should work for TYPO3 v7 and v8
Try this
<img src="{f:uri.image(src : image.uid)}" data-lazy="{f:uri.image(src : image.uid)}" />
You don't have to use the <f:image ..> tag for creating the <f:uri.image ..> returns the same processed resource.
In loop:
<f:for each="{MARKER}" as="file">
<img class="lazy" src=".../blank.gif" data-lazy="{f:uri.image(image: file, width:'XXXc', height:'XXXc', treatIdAsReference:1)}" alt="{file.alternative}" title="{file.title}">
</f:for>

Zend Frameword 2: How to set a html link (img) in a legend of the fieldset?

I used zf2 to design a website.
And the form is something like this:
$this->add(array
'options'=>array(
'label'=> 'title1'))
And finally it shows like this:
<form>
<fieldset>
<legend>title1</legend>
<label>****</label>
</fielset>
</form>
Now, I wanna add a link or an image after the title1, for example:
<form>
<fieldset>
<legend>title1<a href=''>link</a></legend>
<label>****</label>
</fielset>
</form>
How can I do this?
You can't. Well, at least not without overwriting the specific ViewHelper (probably formCollection()). In ZF2 all Labels are run through the Zend\View\Helper\EscapeHtml ViewHelper. Therefore using any sort of HTML inside Labels is not supported in any way.
While going by specification it may be allowed to use inline-elements inside the <legend> Element, semantically it looks a little different. The <legend> shall do nothing but to describe the contents of the <fieldset>.
Anyways, opinions aside, as i've mentioned, you'll have to overwrite the ViewHelper and then skip the use of the EscapeHtml ViewHelper, as it's done in this line of the formCollection() Code