The concept of an object variable in typoscript - typo3

In my typoscript 20.special.value and 10.value.typolink.parameter have the same value, which is a page id. I use this value to build a heading and a menu of its subpages within the same COA object. I would like to be able to re-use this value.
How can I call a object property in typoscript?
Here's what I have tried:
10 = HTML
10 {
value.typolink {
parameter = {$temp.LANDINGPAGEMENU.20.special.value}
}
}
UPDATE:
I am re-utilizing my COA object in different parts of the site, and changing only the special.value, so to display a menu I have:
temp.LANDINGPAGEMENU.10.value.typolink.parameter = 2427
temp.LANDINGPAGEMENU.20.special.value = 2427
temp.COLUMN_NOTSURE < temp.LANDINGPAGEMENU
I am after a cleaner way of handling the
temp.LANDINGPAGEMENU.10.value.typolink.parameter = 2427
temp.LANDINGPAGEMENU.20.special.value = 2427
Full LANDINGPAGEMENU typoscript code is http://pastebin.com/p9kPuZEe

Use the constants but not in a way you tried. You have to define the constant first.
Constants: my_constant = 2427
Setup: parameter = {$my_constant}
...OR...
Assign one of the values by reference using the =< operator. However, this would work only when using the whole object. Example:
temp.something = TEXT
temp.something.value = 2427
...parameter.cObject =< temp.something
I suggest you go with the option 1 using the constants as the 2nd option is somewhat cumbersome.

You can copy the property but not by reference it.

Related

TYPO3 FLUIDTEMPLATE How to switch between different backend layouts and only switch between the templates, not the layouts?

I have following Typoscript for switching backend layout:
10 = FLUIDTEMPLATE
10 {
templateName = TEXT
templateName {
cObject = TEXT
cObject {
data = pagelayout
required = 1
case = uppercamelcase
split {
token = pagets__
cObjNum = 1
1.current = 1
}
}
ifEmpty = Default
}
templateRootPaths {
0 = EXT:package/Resources/Private/Templates/Page/
1 = {$page.fluidtemplate.templateRootPath}
}
partialRootPaths {
0 = EXT:package/Resources/Private/Partials/Page/
1 = {$page.fluidtemplate.partialRootPath}
}
layoutRootPaths {
0 = EXT:package/Resources/Private/Layouts/Page/
1 = {$page.fluidtemplate.layoutRootPath}
}
...
My goal is: I have different backend layouts, like 2 columns, three columns...
When I switch, I want to load 2Columns.html or 3Columns.html from the Resources/Private/Templates/Page/, but keep the Default.html (Main Layout of the Website) in Resources/Private/Layouts/Page/. But I always get the error:
The Fluid template files "/package/Resources/Private/Layouts/Page/2Columns" could not be loaded.
How can I achieve this?
Thanks!
The naming might be misleading.
There are a lot of templates in the world of TYPO3:
there are typoscript configurations which are called template. These consists of records (table sys_template) or files (*.typoscript)
there are HTML-files which includes pattern how the page should be generated (classical HTML-template)
2.a. there are marker-templates for the old way
2.b. there are FLUID-templates. These are divided into three categories which are stored in separate folders named for their purpose:
2.b.I. Templates
2.b.II. Partials
2.b.III. Layouts
And with category 2.b.I. we get another template.
If you use FLUID the primary decision for an appearance of a page is done with the template you start with.
Also that is the only entry in selecting any FLUID files.
Inside this selected template file (= from the folder Templates/) you can select a layout file. With this concept you can have different appearances (e.g. one-, two-, three-columns) with common parts like header/ footer.
In the layout file you define those parts of a page which are common to different templates.
In the partial files you define smaller parts which can be used multiple times or which just make a separate unit (e.g. a menu, or the way you want to include images)
The other non unique name is layout:
Inside the FLUID templates we had the category layout(2.b.III)
but there also are fields in some records named layout: tt_content.layout, pages.layout, pages.backend_layout, pages.backend_layout_next_level
These can make a difference in the appearance of the data.
But that must be configured.
Your example uses pagelayout which gets filled from the fields pages.backend_layout, pages.backend_layout_next_level with inheritance and override, so you can easily use it. and correctly you select a (FLUID-)template.
So: your definition is correct.
You can not select FLUID-layouts from typoscript and you do not need it.

Retrieve content element field from within a plugin template?

I am modifying the template of a plugin, and I want to retrieve a field from the content element.
Using f:debug I see the only data available is from the plugin itself, and none from the content element.
Is there any way I can perhaps insert the field I need in the plugin settings?
eg. something like:
plugin.tx_plugin.settings {
contentUid = TEXT
contentUid.field = uid
}
The best way I can think of to do this is with a custom ViewHelper. Something like:
namespace MyVendor\MyExtension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class ContentUidViewHelper extends AbstractViewHelper
{
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
return $configurationManager->getContentObject()->data['uid'];
}
}
In your Fluid template:
<mynamespace:contentUid />
This will get the uid of the content element, but you can get any field this way. Just change the key of the data array to the field you need.
In the corresponding method (like the listAction or showAction) of the controller you can get the data of the content element in the following way:
$contentObject = $this->configurationManager->getContentObject();
$this->view->assign('contentObjectData', $contentObject->data);
As far as I know, you can't get to that data using typoscript, but I've never needed it anyway since I've been using the above code in the controller.
settings do not have stdWrap-type per default, but only string. So you can not use cObjects as values.
For one (or a few) settings, you could do the stdWrap-processing in your method/class yourself:
$settingsAsTypoScriptArray = $this->objectManager->get(TypoScriptService::class)->convertPlainArrayToTypoScriptArray($this->settings);
$contentObj = $this->configurationManager->getContentObject();
if ($contentObj === null) {
$contentObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
}
// now override the values in the settings array with the processed value
$contentUid = (int)$contentObj->stdWrap($settingsAsTypoScriptArray['contentUid'], $settingsAsTypoScriptArray['contentUid.']);
If you wanna have many settings to be stdWraped, have a look into EXT:news. Georg implemented an interesting concept via useStdWrap configuration.

TYPO3: How can I access property of objects in a partial or section?

I have an object defined in TypoScript
page.10 {
variables {
myObject = COA
myObject{
1 = TEXT
1.value = yome Text
2 = TEXT
2.value = 42
}
}
}
and I need the data of the myObject in a partial
<f:render partial="myPartial" arguments="{content:myObject}" />
that looks like
<section id="myPartial">
<h2>{content.1}</h2>
<p>{content.2}</p>
</section>
Although the content is there ( because {content} will display all the properties) I cannot access it and h2 and p will be empty...
What should I do to fill h2 and p with the content of myObject?
That is not possible. TypoScript only returns text strings at the moment, not arrays. Thus the variable myObject contains the whole concatenated string of the COA, thus yome Text42.
Note that COA means Content Object Array, but the whole COA is one single object that is returned as one string.
Alternative: use the VHS extension's v:var.typoscript ViewHelper:
{namespace v=Tx_Vhs_ViewHelpers}
{v:var.typoscript(path: 'page.10.variables.myObject') -> v:var.set(name: 'myObject')}
After which you can access {myObject.1} etc. in your template. Note that the so-called "chained" usage of v:var.set is optional, but will make it easier to access your variables using an intermediate template variable instead of more expensive calls to retrieve the value completely in multiple locations. The other way:
{v:var.typoscript(path: 'page.10.variables.myObject.1')}
{v:var.typoscript(path: 'page.10.variables.myObject.2')}
etc.
VHS extension on TER: http://typo3.org/extensions/repository/view/vhs

Calling TYPO3 plugin's method in TypoScript?

is it possible to call a method of a plugin from within TypoScript? I need to pass the output of a method to a TypoScript TEXT object.
This is how I imagine it (it is not a correct TypoScript code though):
lib.field_some_field.value.wrap < plugin.some_plugin.some_method
Is it possible?
Thanks!
untested:
# If you are using an USER Object
includeLibs.some_plugin = EXT:some_plugin/pi1/class.tx_some_plugin_pi1.php
lib.field_some_field_with_stdWrap.append < USER
lib.field_some_field_with_stdWrap.append {
# you need includeLibs only, if you use an USER_INT Object
includeLibs = EXT:some_plugin/pi1/class.tx_some_plugin_pi1.php
userFunc = tx_some_plugin_pi1->some_method
}
But you need to set in localconf.php / via Install-Tool:
$TYPO3_CONF_VARS['FE']['userFuncClassPrefix'] = false
And some_method will be called tx_some_plugin_pi1->some_method($content, $conf), you cannot change the parameters!
or
If it is your extension, you could simply check for an conf-variable.
lib.field_some_field_with_stdWrap.append < plugin.some_plugin
lib.field_some_field_with_stdWrap.append.useMethod = some_method
Now check in your main() method for $conf['useMethod'].

SharePoint - Set custom publishing page layout custom field programatically

I have a custom publishing page content type, based on the Publishing Article Page content type. On this content type, I have a custom field named "PageContentCategory". In my code to create new pages, I tried this:
PublishingPage newPublishingPage = this.currentPublishingWeb.GetPublishingPages().Add(pageName, newPageSelectedLayout);
if (pageContent.IsEmpty())
{
pageContent = Properties.Resources.EAWorldArticleHandler_CreateNewArticlePage_DefaultPageContent;
}
newPublishingPage.ListItem[new Guid("{93496B35-7EC3-4132-B0D0-3BDC5606F5EF}")] = pageContentCategory;
newPublishingPage.ListItem[FieldId.PublishingPageContent] = pageContent;
newPublishingPage.Title = pageTitle;
newPublishingPage.Update();
I have also tried to set it by the field name:
PublishingPage newPublishingPage = this.currentPublishingWeb.GetPublishingPages().Add(pageName, newPageSelectedLayout);
if (pageContent.IsEmpty())
{
pageContent = Properties.Resources.EAWorldArticleHandler_CreateNewArticlePage_DefaultPageContent;
}
newPublishingPage.ListItem["PageContentCategory"] = pageContentCategory;
newPublishingPage.ListItem[FieldId.PublishingPageContent] = pageContent;
newPublishingPage.Title = pageTitle;
newPublishingPage.Update();
Both of these methods throw an error. Is there any way for me to set my custom field's value in code like this?
Try calling the Update method on newPublishingPage.Listitem not on newPublishingPage itself.
Like this:
newPublishingPage.ListItem["PageContentCategory"] = pageContentCategory;
newPublishingPage.ListItem.Update();
and then you maybe also need some of these lines, depending in the configuration of your page library
newPublishingPage.Checkin();
newPublishingPage.Publish();
newPublishingPage.Approve();
So, the solution to my problem was that I had to programmatically add the content type to the pages list instead of letting it be added automatically the first time a page with that content type was added. Apparently if you let SharePoint automatically add the content type to the pages list then it somehow doesn't get bound properly. So adding the content type first solved my problem.