Add CSS class to imageLinkWrap - typo3

I can't add a CSS class to an image over
imageLinkWrap.linkParams.ATagParams.dataWrap = class="popup-image"
when I change: if ($content == $string) {} to if ($content) {} in TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer function imageLinkWrap the class will be added.
Is this normal or am I doing something wrong?

Did you try it without a dataWrap?
imageLinkWrap.linkParams.ATagParams = class="popup-image"
Since you are using a static text and not a variable, you do not need a "wrap". You can simply use it so, as linkParams used as a typolink.

Related

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.

How can I display the version of my sitepackage in the frontend?

I want to display the version of my sitepackage (from my declaration file ext_emconf.php ) in the frontend.
How do I query this information? I was thinking of using a DataProcessor in my FLUIDTEMPLATE, but I’m not sure whether I need to write my own or if there’s already one I can use for that.
Thank you!
Depending on your exact needs you could make use of ExtensionManagementUtility::getExtensionVersion() to inject a global TypoScript constant via ExtensionManagementUtility::addTypoScriptConstants():
// ext_localconf.php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptConstants(sprintf(
'site.version = %s',
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getExtensionVersion('sitepackage')
));
Afterwards you can use this constant anywhere in TypoScript setup including variables of Fluid templates:
// TypoScript setup
10 = FLUIDTEMPLATE
10 {
// ...
variables {
siteVersion = {$site.version}
}
}
Now use this variable anywhere you like in your template:
<!-- Fluid template -->
<p>Site {siteVersion}</p>
There is no DataProcessor for that.
I'd suggest to create a small PHP class to read out the version and integrate it via TypoScript as a USER object.
namespace Vendor\Sitepackage\Service;
class SitepackageVersionService
{
public function getVersion(): string
{
$version = '';
$packageManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Package\PackageManager::class);
$extensionKey = 'my_extension_key';
if ($packageManager->isPackageActive($extensionKey)) {
$package = $packageManager->getPackage($extensionKey);
$version = $package->getPackageMetaData()->getVersion();
}
return $version;
}
}
page.10.variables.sitePackageVersion = USER
page.10.variables.sitePackageVersion.userFunc = Vendor\Sitepackage\Service\SitepackageVersionService->getVersion
<strong>Version: {sitePackageVersion}</strong>

Disable the default constructor on a Database-First workflow

How can I prevent the use of the parameterless constructor of the generated DbContext?
var dcx = new DataEntities();
The default constructor is generated by the T4 template, and I thus cannot override it in a partial class. I would prefer it not compile, but a runtime error would also be good.
You can modify the template to provide the constructor you want.
Open the *.Context.tt file
Go to line ~59
Change this code.
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
Into the default constructor you want, for example.
public <#=code.Escape(container)#>(string nameOrConnectionString)
: base(nameOrConnectionString)
Save
You can inherit the DbContext created by the template, define your own constructor, and use the inherited DbContext instead of the one generated by the template.
public class MyModifiedDbContext : TheTemplateGeneratedDbContext
{
public MyModifiedDbContext()
{
// define your own constructor
}
}
Or make it private to avoid its use, so you get the error at compile time
public class MyModifiedDbContext : TheTemplateGeneratedDbContext
{
private MyModifiedDbContext()
// ...
}
Use MyModifiedDbContext instead of TheTemplateGeneratedDbContext
I gave up waiting for EF Core team to add this as an option. I don't want to make and maintain my own T4 templates for this - that's nuts!
Solution for me was just to run some regex on the generated code as part of a powershell script.
fix-dbcontext.ps1
$filename=$args[0]
# load context file
$content = (Get-Content -Raw $filename)
[regex] $commentOutConstructorRegex = '(?ms)(?<=: DbContext\s*.*?)(public.*?)(?=\s*public)'
$content = $commentOutConstructorRegex.Replace($content, '// Default constructor removed', 1)
[regex] $removeOnConfiguringRegex = '(?ms)(protected override void OnConfiguring).*?(?=\s*protected)'
$content = $removeOnConfiguringRegex.Replace($content, '// Generated OnConfiguring removed', 1)
[regex] $dateCommentRegex = '(?ms)(?=\s*public partial class)'
$content = $dateCommentRegex.Replace($content, "`r`n`t// Generated " + (Get-Date).ToString() + "`r`n", 1)
$content | Out-File -Encoding UTF8 $filename
This will:
Remove the default constructor
Remove the OnConfiguring method including hardcoded connection string
Add the date in a comment
Just run it with .\fix-dbcontext.ps1 .\MyDBContext.cs.
You probably want to change that last line to context.txt instead of $filename until you're sure it does what you want.
IMPORTANT: This was tested only on EFCore templates, but if you understand my Regexes you should be able to modify it for EntityFramework if it doesn't already work.

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'].

Zend: Quick and succinct way of inserting custom HTML into a Zend_Form?

Is there some method that accepts inserting custom html without having to actually add form controls, even if they're hidden and making my html a decorator?
I'm looking for something like:
$this->addCustomElement( array(
'div',
'body' => '<p>inner text</p>'
) );
I need something short and quick, I don't want to create a new class or something overkill.
Well it's really as simple as this:
$note = new Zend_Form_Element('note');
$note->helper = 'formNote';
$note->setValue('<b>hi</b>');
$form->addElement($note);
But the problem is that when you submit the form, the form calls $note->isValid(), which overrides the value, so if there are errors with the form, the next time you display it, the custom HTML won't be shown. There are two easy ways to fix this, the first is to override isValid() in your Form class like this:
public function isValid($data)
{
$note = $this->note->getValue();
$valid = parent::isValid($data);
$this->note->setValue($note);
return $valid;
}
But personally I find this kinda hackish way, and prefer the second option. That is to write a very simple class (this should really be part of Zend itself, I have no idea why it isn't, since it includes a formNote view helper, but no element that uses it):
class My_Form_Element_Note extends Zend_Form_Element_Xhtml
{
public $helper = 'formNote';
public function isValid($value, $context = null) { return true; }
}
Then you just have to do:
$note = new My_Form_Element_Note('note');
$note->setValue('<b>hi</b>');
$form->addElement($note);
And everything will just work.
Other options include doing some black magic with decorators, but I really recommend you to not go down that path.
Also note the AnyMarkup Decorator.