tx_news: extend with a second container $contentElements - typo3

TYPO3 8.7.4
news 6.0.0
Is it possible to extend news in a news_extend extension with a second container? (like contentElements)
The goal is to place this second container in the related content of the detail page.
Is there an example?

Yes, it's easy. You need to add field to database, configure it in TCA, extend the news model and adjust the detail template.
in news_extend/ext_tables.sql add:
CREATE TABLE tx_news_domain_model_news (
tx_newsextend_content_elements_second text
);
in news_extend/Configuration/TCA/Overrides/tx_news_domain_model_news.php:
$newNewsColumns = [
'tx_newsextend_content_elements_second' => [
// .... here copy the original 'content_elements' field's config from ext news' TCA. update the label to yours.
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tx_news_domain_model_news', $newNewsColumns);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tx_news_domain_model_news', 'tx_newsextend_content_elements_second', '', 'after:content_elements');
in news_extend/Resources/Private/Language/locallang_db.xlf add:
...
<trans-unit id="tx_news_domain_model_news.tx_newsextend_content_elements_second">
<source>Additional content elements</source>
</trans-unit>
news_extend/Classes/Domain/Model/News.php:
namespace [my vendor]\NewsExtend\Domain\Model;
class News extends \GeorgRinger\News\Domain\Model\News {
// here copy all uses of contentElement field from original model, only name it txNewsextendContentElementsSecond.
// watch whether it's only declared property and getter/setter (simple fields), or something more is done in the model and do it the same way as there.
// tip: see getContentElementIdList() method
}
register your extension as provider of news' model extending class:
in news_extend/ext_localconf.php add:
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['classes']['Domain/Model/News'][] = 'news_extend';
now you can use this in your template:
<f:if condition="{newsItem.txNewsExtendContentElementsSecond}">
<!-- content elements second -->
<f:cObject typoscriptObjectPath="lib.tx_news.contentElementRendering">{newsItem.txNewsExtendContentElementsSecondIdList}</f:cObject>
</f:if>
Above may not just work if you copy-paste it, I'm writing it from my notes. But it will help you to get the idea. Good luck

This should work. Just extend the news tca and model as described in the documentation

Related

form framework in news detail view

I tried to implement a form with form framework in the news detail view. The basic way is explained here:
https://docs.typo3.org/c/typo3/cms-form/10.4/en-us/I/Concepts/FrontendRendering/Index.html#render-within-your-own-extbase-extension
Viewhelper:
<formvh:render persistenceIdentifier="EXT:myext/Resources/Private/Forms/myforms.form.yaml"/>
Form definition:
renderingOptions:
controllerAction: detailAction
addQueryString: true
submitButtonLabel: Absenden
fluidAdditionalAttributes:
class: ''
identifier: myForm
label: 'myLabel'
type: Form
prototypeName: myPrototype
The form is displayed. When I submit the form the news detail view is shown again including the form, but it's empty. The form is not processed. Something is missing, but I cannot find it in the manual.
Thanks!
I think the important part is written in the note below the linked paragraph:
In general, you can override each and every form definition with the help of TypoScript (see ‘TypoScript overrides’). This feature is not supported when you are rendering forms via the RenderViewHelper.
Luckily, there is a solution for your problem: use the ‘overrideConfiguration’ parameter instead. This way, you can override the form definition within your template. Provide an according array as shown in the example below.
<formvh:render persistenceIdentifier="EXT:my_site_package/Resources/Private/Forms/MyForm.yaml" overrideConfiguration="{renderables: {0: {renderables: {0: {label: 'My shiny new label'}}}}}"/>
That means you can check for post-variables by TypoScript conditions and adjust the controllerAction (and view) accordingly. The show / detail action is not processing the form usually, so it's logical that another action has to be assigned. I'm not sure in the moment if it does matter if double opt-in or a confirmation page shall be shown, that might depend on the form-extension.
After some hours of experimenting i was able to solve the problem. It ist simply a matter of caching ...
Georg has implemented in news a special caching engine which ignores the config.no_cache = 1 definition in setup. So the detail view of news is always cached even when the whole installation ist set to config.no_cache = 1. So this combination seems to work:
Viewhelper in Detail.html:
<formvh:render persistenceIdentifier="EXT:myext/Resources/Private/Forms/myforms.form.yaml"/>
And this definitions in the yaml file of the form:
renderingOptions:
controllerAction: detail
addQueryString: true
submitButtonLabel: Absenden
additionalParams:
no_cache: 1
identifier: myForm
label: 'myLabel'
type: Form
prototypeName: myPrototype
This renders the whole page without cache which is not optimal. It would be better when only the news entry is rendered without cache. and there is the problem, that in many installations the parameter 'disableNoCacheParameter' is set in the localconfiguration file which disallowes no_cache=1 in urls.
So i looked for an other - better - possibility to work around this problem.
First make a new fluid template anywhere in your resources folder with the modified viewhelper from above:
<formvh:render persistenceIdentifier="{settings.persistenceIdentifier}"/>
Then write a typoscript like this:
lib.embeddedForm = COA_INT
lib.embeddedForm {
10 = FLUIDTEMPLATE
10 {
file = EXT:myext/Resources/Private/Forms/myForm.html
settings {
EXT:myext/Resources/Private/Forms/myforms.form.yaml
}
extbase {
pluginName = Formframework
controllerExtensionName = Form
controllerName = FormFrontend
controllerActionName = perform
}
}
}
And final you can embed the form with
<f:cObject typoscriptObjectPath="lib.embeddedForm" />
as COA_INT in the news template. This disables the caching of the form.
Perhaps it helps ...

TYPO3 Custom File Name for rendered images

I wanted to ask if in TYPO3 LTS 11 is a way to change how TYPO3 generates the name for a rendered image?
In the template I use the f:image Viewhelper with cropVariant option to generates the image (done by TYPO3 Image Rendering).
<f:image image="{file}" cropVariant="desktop" />
That Image then has a name something like this: csm_my-image_88ade60319.jpg
Can I define how TYPO3 should name those rendered images?
For example to "my-image_large.jpg"
The cms_ part of the filename is hardcoded in the TYPO3\CMS\Core\Resource\Processing\ImageCropScaleMaskTask::getTargetFileName function. The hash at the end is added in the TYPO3\CMS\Core\Resource\Processing\AbstractGraphicalTask::getTargetFileName function. Not sure why cms_ is added, but the hash is to make sure the file name is unique. The hash is generated using the file and configuration.
So by default it isn't possible. If you really want different file names you can XCLASS TYPO3\CMS\Core\Resource\Processing\ImageCropScaleMaskTask with something like:
<?php
namespace Vendor\MyExtension\Resource\Processing;
class ImageCropScaleMaskTask extends \TYPO3\CMS\Core\Resource\Processing\ImageCropScaleMaskTask
{
public function getTargetFileName()
{
$originalFileName = parent::getTargetFilename();
$fancyFileName = ... // Do your things to change the file name
return $fancyFileName;
}
}
You'll probably also want to add something to configure what the file name should be. So you'd probably also need to XCLASS the TYPO3\CMS\Fluid\ViewHelpers\ImageViewHelper class or create a new ViewHelper to add some settings to the processing instructions.
Just make sure the file name is unique or you might get weird results.

TYPO3 write name of sys_category into class name at tx_news

I'using TYPO3 8.7 and write the name of a sys_categoryinto the class name of tx_news-template Item.html, like this:
<div class="{f:format.case(value: '{newsItem.firstCategory.title}', mode: 'lower')}"> ...
Now one of my categories has two words, like 'my category', so the classname results:
<div class="my category">
How can I remove the empty ' ' from class name in FLUID?
Thanks for your help.
Also i would think about using the category uid instead of category name. As names are brittle. An editor might rename somthing and your css code breaks. But your pretty save if you use uids
This is not possible by default - However I see the following options:
1) Create a custom ViewHelper: This would be the best solution as you don't need any 3rd party extension as dependency.
2) Misuse a different field of the category record like seo_title, description or similiar
3) You could use the replace VH of EXT:vhs, see https://fluidtypo3.org/viewhelpers/vhs/master/Format/ReplaceViewHelper.html
You could adjust your css to recognize double classes as well.
.category
.my.category
Still the way to go should be unique identifiers instead of names or titles.

TYPO3: category tree of tx-news, render sub-tree only if main is selected

I override Templates/Styles/TWB/Templates/Category/List.html to have the category menu behave exactly as the sidebar menu in the introduction package (submenus show only if main is selected).
If I add the static template "News Styles Twitter Bootstrap (news)" I'm almost there, it is not difficult to open the sub-categories only if the main category is selected (I need a massive amount of categories/sub-categories), but it should also be open when a sub is selected:
...
<f:if condition="{0:category.item.uid,1:category.item.uid} == {0:overwriteDemand.categories,1:category.children.{overwriteDemand.categories}.parent}">
<f:if condition="{category.children}">
<f:render section="categoryTree" arguments="{categories: category.children,overwriteDemand:overwriteDemand,class:''}" />
</f:if>
</f:if>
...
I do not know how to use {overwriteDemand.categories} as key to match the value ... can anybody point to the proper syntax
update: I tried to apply a custom ViewHelper as this post suggests, but using TYPO3 V7.6.16 got stuck with the error should be compatible with TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper:‌​:render(), so could not try working with the variable overwriteDemand.categories in another way ...
Dynamic access to variables in fluid is just possible since TYPO3 8. Check out the Whats New Slides here: https://typo3.org/download/release-notes/whats-new/ and search for "Dynamic variable name parts" in the PDF.
In TYPO3 7, the "vhs"-Extension provides a ViewHelper to do the same job but nesting a ViewHelper within an complex f:if-condition is even more difficult. If possible, try out TYPO3 8. If it's not possible you may write your own ViewHelper to solve this logical problem.

Using ViewHelper inside a partial path

I'm working on a new extension and my model has the attribute 'type' which can get different strings from the TCA form. Strings only!
The name of the partial that my template should load is inside the 'type' attribute from my model. So here comes my problem. Since TYPO3 4.7.x the .html file names for fluid have to start with an uppercase letter. Inside the 'type' attribute the name of the partial that should be loaded is always lowercase. For that, I wrote a simple view helper that contains only this method:
public function render($string) {
return ucfirst($string);
}
Inside my template I tried to use this view helper for the path to the partial:
{namespace vh=Tx_MyExtension_ViewHelpers}
<f:for each="{obj.subObjects}" as="sub">
<f:render partial="OtherObject/{vh:String.UpperFirstCharacter(string:'{sub.type}')}" arguments="{sub:sub}" />
</f:for>
If I try to load this in the fontend, nothing from my extension will be rendered and there are no error messages anywhere. The problem depends on my view helper, 'cause even if I try to load only this:
{vh:String.UpperFirstCharacter(string:'test')}
{vh:String.UpperFirstCharacter(string:'{sub.type}')}
There is nothing comming back. If I only output {sub.type} it shows me the string that I want, but in lowercase.
Obviously your problem is that you're ViewHelper doesn't do what you want it to do.
First of all, ViewHelper names are to be written in lowerCamelCase.
Second, you don't need to place sub.type in curly braces:
This syntax...
{vh:string.upperFirstCharacter(string:sub.type)}
... should be sufficient.
Fluid will then look for a ViewHelper named
Tx_MyExtension_ViewHelpers_String_UpperFirstCharacter
or namespaced
\My\Extension\ViewHelpers\String\UpperFirstCharacter
Please check that this is the case.
So I found the issue. Fluid can't handle namespaces. So first my ViewHelper looked like this:
<php
namespace TYPO3\MyExtension\ViewHelpers\String;
class UpperFirstCharacterViewHelper ...
Now I changed the name of my class and removed the namespace:
<php
class Tx_MyExtension_ViewHelpers_String_UpperFirstCharacterViewHelper ...
This is how it works. At the moment I work with TYPO3 6.1.6.
Thank you anyway lorenz for your help!
EDIT:
I went fully retarded! Fluid CAN handle namespaces. I just had to set the namespace the right way.
That's how you set the namespace inside the template:
{namespace vh=TYPO3\MyExtension\ViewHelpers}
On top of this comment you can see how my ViewHelper looks like with a namespace.