Override twig template from plugin - twig

I would like to override a block from a twig template from a plugin in my own plugin.
I have overridden native shopware templates in the past, but I have troubles with plugin templates.
The plugin I am trying to adjust is FroshProductCompare and I am also using FroshDevelopmentHelper to easily retrieve the template I am trying to adjust.
Via the development helper, I found out that the template is located at
vendor/store.shopware.com/froshproductcompare/src/Resources/views/storefront/component/compare/section/overview.html.twig
So I created the file at
custom/plugins/ExamplePlugin/Resources/views/storefront/component/compare/section/overview.html.twig
and added
{% sw_extends "#FroshProductCompare/storefront/component/compare/section/overview.html.twig" %}
to the first line of the file.
I have also tried
{% sw_extends "#Storefront/storefront/component/compare/section/overview.html.twig" %}
I have built the storefront and cleared the cache multiple times and I have also reinstalled the plugins in different orders without success.
I found similar questions, which are not the same.
E.G. How to do a template multiple inheritance in Shopware 6?
But the difference here is, that the block is not native to shopware and is created by the plugin.
Any ideas?

The issue is most likely due to plugin load order.
tl;dr: Older plugins (based on installation date) take precedence over newer plugins. But if you want to make sure your plugins take precedence defined the load order in your theme.
It starts with finding the right template in \Shopware\Core\Framework\Adapter\Twig\TemplateFinder::find you can see a queue is build based \Shopware\Core\Framework\Adapter\Twig\TemplateFinder::getNamespaceHierarchy which in turn gets it from \Shopware\Core\Framework\Adapter\Twig\NamespaceHierarchy\NamespaceHierarchyBuilder. The method return the first found template to the order is the key.
The NamespaceHierarchyBuilder is tagged with shopware.twig.hierarchy_builder which is used to inject the following builders:
Shopware\Core\Framework\Adapter\Twig\NamespaceHierarchy\BundleHierarchyBuilder with priority 1000
Shopware\Storefront\Theme\Twig\ThemeNamespaceHierarchyBuilder with priority 500
Since you want to overwrite a template from a plugin with a plugin BundleHierarchyBuilder is the interesting one (all plugins are simply symfony bundles).
BundleHierarchyBuilder is getting the bundles from the kernel (\Shopware\Core\Kernel). The kernel registers the bundles in \Shopware\Core\Kernel::registerBundles and uses an instance of \Shopware\Core\Framework\Plugin\KernelPluginLoader\KernelPluginLoader to load the plugins. The used instance is \Shopware\Core\Framework\Plugin\KernelPluginLoader\DbalKernelPluginLoader as you can see in \Shopware\Core\HttpKernel::createPluginLoader.
As described in this answer DbalKernelPluginLoader loads the plugins based on the installation date. So plugins with an older installation date will be higher up in the list in the TemplateFinder and their template will be returned.
I would actually recommend you this solution: Define the load order in your own theme.

Related

Is the order of the bundles/apps/plugins inside the generated file var/plugins.json in Shopware 6 important?

When developing store bundles/apps/plugins in Shopware 6, the file var/plugins.json often has to be generated since it is needed for the build scripts, for example bin/build-administration.sh in the Shopware 6 production template.
Depending on the branch that is being worked on, different bundles/apps/plugins are active. The file var/plugins.json is of course different in each branch, but the order of contents is constantly changing since the bundle:dump command has no integrated sorting which leads to repeated merge conflicts similarly to the composer.lock file, since the order of items changes most of the time.
A possible solution is to ksort the array of bundles/apps/plugins before it gets written into var/plugins.json. However, I'm wondering if this could lead to problems, for example should one plugin be dependent on another. So my question is: Is the order of the bundles inside the generated file var/plugins.json in Shopware 6 important?
The plugins are sorted ascending by the date stored in plugin.installed_at. This affects the order of template inheritance within plugins for example, so generally speaking it matters. Within the plugins.json however I'm not exactly sure if it does though, since it seems to be used by the webpack.config.js for injecting a possible custom webpack config of a plugin, which I think should not come in conflict with each other no matter what the order is.

Shopware 6 - bug with Email template variables

Did someone has a problem with email templates?
In my case when I use email template in Flow builder for trigger "checkout.order.payment_method.changed" email template with type "order confirmation" doesn't work properly. Problem with variables: currency and addresses are null but other variables works properly.
Interesting when I use the same template in Flow builder for trigger "checkout.order.placed" all vars working properly.
p.s. I've updated all extensions and my Shopware version is v6.4.9.0 Stable Version
Maybe it's a Shopware bug or conflict between plugins?
There are some inconsistencies regarding the data available between different Flow-Builder Events. I noticed something similar and created an issue for it here.
Maybe you can add your case there as this sounds related.
Without knowing the exact content of your order confirmation template, eg if it is the default content or if you made changes, it is hard to tell why this wouldn't work. I tested this on the latest release as of today 6.4.13.0 and the combination of said trigger and template seems to work fine. Looking at the history of the OrderStateChangeEventListener, the criteria for the order should've included currency and addresses associations for a while already, including your version. As #newgennerd already said there could potentially be differences between the criteria used for fetching order for state change events and those used for order placed events, as the latter would be the common use case for the order confirmation. So you should keep that in mind.

Write custom grid layouts with extbase/fluid but without any extension like gridelements

I look for a tutorial, help or an example that tells me what I have to do to write a grid element like 2-colums in basic typo3 (v9) with fluid but no other extension like gridelements, DCE, Templa Voila, etc. I want the same gridelements can do but I dont want to be depended to this extention and move it in my own site extention.
I tried the same with normal content elements (CE) like here:
https://docs.typo3.org/c/typo3/cms-fluid-styled-content/9.5/en-us/AddingYourOwnContentElements/Index.html
But how can I nest a CE in a CE? And how can I do this by drag&drop in the backend?
You can't. The page module doesn't support nesting
You can't nest CEs in a CE. On database level this would mean that you have to make a tt_content record a subrecord of a parent tt_content record. You run into several problems, basically the multilanguage support will be broken and the shortcut element does not function as you will expect it to. That is why the extensions "gridelements" and "mask" exist.
I integrated the gridelements configuration into my sitepackage. So I do not need to bother anymore with it.
Just for your info:
There is now an initiative that works on integrating this functionality into the core (Structured Content Initiative, https://typo3.org/article/a-structured-content-initiative/). Stay tuned to it.
There is nothing special about providing Gridelements via external files, since it's based on TSconfig, TypoScript and Fluid. That's why there is not that much about it in the documentation, since it's the same thing you would do with any other kind of sitepackage. The TSconfig and TypoScript parameters are already explained there, while the Fluid would be up to you anyway.
To have a kind of kickstarter just take any extensions providing Gridelements layouts as an example. A very popular one would be bootstrap_grids, which can be found in the TER or here: https://github.com/laxap/bootstrap_grids
You don't necessarily need the flexform controller of that extension, but the Configuration and Resources folders, show you how to configure stuff and you can see how that is included via ext_localconf.php
There are even comments i.e. in the TSconfig files to explain what is possible there and how to handle i.e. mixed environments with record and file based setups. Although it would be recommended to go for files.
You would at least have to add the necessary backend rendering methods to a draw item hook, that will modify the preview of the container element.
So basically you would have to rewrite everything that DCE, Flux, Gridelements or other similar extensions already do.
Which brings us to the question, why you want to avoid those extensions, since especially those three are well known, widely spread, well supported and available for currently supported TYPO3 versions.

Kentcio v9 Smart Search Dialog with Results search mode localization

How can i localize the drop down option for the search mode? I did some digging and was able to adjust the localization for the search form labels but i'm at loss here.
The CMS Module SearchDialog.ascx call the drop down list here, but i can't see where the values come from.
<cms:CMSDropDownList runat="server" ID="drpSearchMode" CssClass="DropDownField" />
Go to the localization App and create resource strings for
"srch.dialog.AllWords"
"srch.dialog.AnyWord"
"srch.dialog.anywordorsynonyms"
"srch.dialog.ExactPhrase"
Believe those are the 4 you need.
I couldn't find official documentation that helps much with this, though there have been articles in the past on older versions. However, one trick I've used previously is to look in the ~/CMSResources/cms.resx file, find the localized string there, and add a new one with the same key to the Localization module in Kentico. That is, add a new resource string in Kentico with the same key (the naming will be different depending on your version of Kentico).
Here's the docs discussing setting up a multilingual interface: https://docs.kentico.com/display/K9/Setting+up+a+multilingual+user+interface
And here's a screenshot of the resx file:
So in your case I'd create a new resource string within Kentico called "srch.dialog.allwords" as an example and that should overwrite and take priority over whatever is in the .resx file, plus you can manage it via the Kentico admin. There may be a quicker or more reliable way to view the list of default resource strings but in my recent installs of Kentico, the list is hidden from the admin interface.
Alternatively, of course, you could manage the resource strings via various .resx files as in the documentation, but I try to manage as much of these pieces via Kentico as possible for convenience.

Adding new section in control panel of Liferay

I want to add a new section in control panel of liferay and within that section I want to have my custom-portlet. I did it using ext. However I want to do it with hook . Is it possible ?
I don't think it would be that easy with a hook, because of the following reasons:
You can't modify in a Hook - the class com.liferay.portal.util.PortletCategoryKeys which contains the keys for displaying the different sections. The different sections are hard-coded in this class in a String array ALL.
You can't modify the logic of PortalImpl#isControlPanelPortlet() which uses the PortletCategoryKeys#ALL to determine if the request in question is for a control panel portlet.
Then you also have another method which you can't modify with a Hook and is used extensively PortalImpl#getControlPanelCategory()
Doing it with a hook:
I have not tried this but I think if you need to do it with a hook you would have to change all those JSPs which make use of PortletCategoryKeys#ALL and the methods of PortalImpl as stated above, and provide your custom implementation for all these methods in the JSP.
I would really like to know how you implemented it with an EXT may be just the steps or the methods you have overridden. So that I can try to convert those in terms of a hook.
This is as far as my understanding goes. Hope this helps.
With the advent of Marketplace, ControlPanel has a new category named "Marketplace" and that section is introduced in a plugin. However, I never checked if 6.1 GA2 introduced a new section that this plugin just fills. Check the marketplace plugin if you can find a trace of this section implemented there.
On the other hand, nobody has yet named any section that definitely required a new section (though some have asked me how to solve the same problem). For this reason, you might want to re-think the requirement and choose one of the existing sections. If you don't, at least I'd be interested in the name and purpose of the new section - I might find a first one actually justifying this kind of implementation...

Resources