TYPO3 Extbase backend module. Template path issue - php

I'm experiencing a strange problem with extbase/fluid extension creation.
I use TYPO3 6.1
I've made an extension with a backend module on my dev server (same configuration/hardware then the prod). The module works perfectly with the path to the template :
myext/Resources/Private/Backend/Templates
myext/Resources/Private/Backend/Layouts
myext/Resources/Private/Backend/Partials
After this, I downloaded my extension's zip in the ext manager and then installer on the prod server. Now I can't use my extension because the module don't find the templates.
I've configured the extension by the same way. The templates are in the right path.
I test to move my folder to the parent level :
myext/Resources/Private/Templates
myext/Resources/Private/Layouts
myext/Resources/Private/Partials
With this it works, but in the module configuration, I specify the right path to the "Backend/" folder.
I wont to move my folder in the Private folder, I want it to run in the Private/Backend folder.
I've included the extension static template to the website root TS template.
Here's the constants :
module.tx_myext {
view {
# cat=module.tx_myext/file; type=string; label=Path to template root (BE)
templateRootPath = EXT:wng_myext/Resources/Private/Backend/Templates/
# cat=module.tx_myext/file; type=string; label=Path to template partials (BE)
partialRootPath = EXT:wng_myext/Resources/Private/Backend/Partials/
# cat=module.tx_myext/file; type=string; label=Path to template layouts (BE)
layoutRootPath = EXT:wng_myext/Resources/Private/Backend/Layouts/
}
persistence {
# cat=module.tx_myext//a; type=string; label=Default storage PID
storagePid =
}
}
And here's the setup :
module.tx_myext {
persistence {
storagePid = {$module.tx_myext.persistence.storagePid}
}
view {
templateRootPath = {$module.tx_myext.view.templateRootPath}
partialRootPath = {$module.tx_myext.view.partialRootPath}
layoutRootPath = {$module.tx_myext.view.layoutRootPath}
}
}

The main problem will be that the typoscript configurations will not get loaded on storage folders or pages without an template in the root path.
Explaination:
typoscript configuration you will set for your extension wether it is in ext_typoscript_setup, an static template or via php it will always need an system record template somewhere in the root of the page. otherwise it will not get rendered - and no path settings for your extbase extensions will happen, so the default layout, template and partial path is set and thats the place the script will look for your stuff.
Default is:
/Private/Resources/Layout/
/Private/Resources/Partials/
/Private/Resources/Templates/#Controllername/#Actionname
if you need to override these for your backendmodule you can work around that problem by injecting the settings for the view directly in your controller.
<?php
namespace VendorKey\ExtensionName\Controller;
class SettingsController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* Initializes the controller before invoking an action method.
* #return void
*/
protected function initializeAction() {
$this->setBackendModuleTemplates();
}
/**
* Set Backend Module Templates
* #return void
*/
private function setBackendModuleTemplates(){
$frameworkConfiguration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
$viewConfiguration = array(
'view' => array(
'templateRootPath' => 'EXT:extension_name/Resources/Private/Templates/Modules/',
'partialRootPath' => 'EXT:extension_name/Resources/Private/Partials/Modules/',
'layoutRootPath' => 'EXT:extension_name/Resources/Private/Layouts/Modules/',
)
);
$this->configurationManager->setConfiguration(array_merge($frameworkConfiguration, $viewConfiguration));
}
/**
* action settings
* #return void
*/
public function settingsAction(){
}
}
i hope this helps
greetz benji

As #benjamin-kott explains, TYPO3's backend modules configurations need to be loaded first. Unfortunately, extension's typoscript files are not automatically loaded by default.
One way of make TYPO3 aware of this typoscript files is creating two files in extension's root folder:
ext_typoscript_constants.txt
<INCLUDE_TYPOSCRIPT: source="FILE:EXT:myext/Configuration/TypoScript/constants.txt">
ext_typoscript_setup.txt
<INCLUDE_TYPOSCRIPT: source="FILE:EXT:myext/Configuration/TypoScript/setup.txt">
(kind of obvious but: you should replace this paths with yours)
After adding this files, you should reinstall the extension to see changes. You can use the TypoScript Object Browser to find out if your setup and constants are being loaded.

Try to clean all caches, even in typo3temp/Core/Cache (or something like that)

I dont realy know ur setup, but normaly you must setup these paths in /Configuration/TypoScript/setup.txt like this
module.tx_yourext {
persistence {
storagePid = {$pid}
}
view {
templateRootPath = {$templateRootPath}
partialRootPath = {$partialRootPath}
layoutRootPath = {$layoutRootPath}
}
}
This configuration does not being used until you add the static template of your extension. Also you should add these lines to the ext_tables.php
if (TYPO3_MODE === 'BE') {
Tx_Extbase_Utility_Extension::registerModule(
$_EXTKEY,
'web', // Main area
'mod1', // Name of the module
'', // Position of the module
array( // Allowed controller action combinations
'Controller' => 'actionName'
),
array( // Additional configuration
'access' => 'user,group',
'icon' => 'EXT:my_ext/ext_icon.gif',
'labels' => 'LLL:EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_mod.xml',
)
);
}

Although this thread is quite old I want to show you guys my solution for TYPO3 7.6 LTS.
First you need to include your TypoScript files via Template > Edit whole record > Includes.
And in your TypoScript you need to use templateRootPaths.0 instead of templateRootPath:
module.tx_extension {
view {
templateRootPaths.0 = EXT:extension/Resources/Private/Backend/Templates/
partialRootPaths.0 = EXT:extension/Resources/Private/Backend/Partials/
layoutRootPaths.0 = EXT:extension/Resources/Private/Backend/Layouts/
}
}

Related

Dynamically resolvable Twig namespaces

I have a Symfony application that handles request from multiple domains. On these domains, customers have the ability to create custom Twig templates that can be used in their CMS module. These templates are saved to a /path/to/ftp/example.com/cms_templates/ directory.
In previous versions of Symfony, rendering these templates was not an issue. On an incoming request on mydomain.com/page_one, the absolute path of the Twig template could be resolved to e.g. /path/to/ftp/mydomain.com/cms_templates/page_one.html.twig. The existence of the template was verified and the template was rendered. However, in Symfony 4 support for absolute template paths has been removed.
I thought of registering an extra Twig namespace in twig.paths called 'custom' that points to /path/to/ftp and then reference the templates with #custom/mydomain.com/cms_templates/page_one.html.twig. The problem is, /path/to/ftp contains not only templates but loads and loads of other files too. And the TemplateCacheWarmer is looping through all of these files.
What I'am actually looking for is a way to register a Twig namespace, say #cms that is resolved on the fly such that I can inject the hostname of the current request in it. I would then be able to reference a template using #cms\page_one.html.twig. Cache warmup isn't necessary for these templates.
How to achieve such functionality? I looked ad the Twig documentation but it looks like I just can't figure it out.
TLDR; How to get Symfony/Twig to resolve the template #foo\template.html.twig to /path/to/domain.com/templates/template.html.twig when domain.com differs between requests.
One solution would be to prepend configuration
public function prepend(ContainerBuilder $container)
{
$bundles = $container->getParameter('kernel.bundles');
if (isset($bundles['TwigBundle'])) {
$config = $container->getExtensionConfig('twig')[0];
$paths = ['/path/to/cms' => 'cms'];
if (array_key_exists('path', $config)) {
$paths = array_merge($config['paths'], $paths);
}
$config['paths'] = $paths;
$container->prependExtensionConfig('twig', $config);
}
}
The problem would be this:
If you are building some kind of CMS - then this would mean - no other bundle/module/plugin could ever register additional twig namespaces again - if I am right.
So... I am interested in other solutions if there are some.

TYPO3 issue with Typoscript and accessing $this->settings

I'm using TYPO3 version 7.6.14 and I've created an extension for client which has four controllers, four plugins and its pretty big overall. Anyway now I'm required to add option (settings variable) for dynamic or user selected "page id" which is then used to redirect from one plugin to another. There might be better solution for my problem but I'm trying to do something like:
plugin.tx_extname_basket {
view {
# cat=plugin.tx_extname_basket/file; type=string; label=Path to template root (FE)
templateRootPath = EXT:extname/Resources/Private/Templates/
# cat=plugin.tx_extname_basket/file; type=string; label=Path to template partials (FE)
partialRootPath = EXT:extname/Resources/Private/Partials/
# cat=plugin.tx_extname_basket/file; type=string; label=Path to template layouts (FE)
layoutRootPath = EXT:extname/Resources/Private/Layouts/
}
persistence {
# cat=plugin.tx_extname_basket//a; type=string; label=Default storage PID
#storagePid =
}
settings {
# cat=plugin.tx_extname_basket//a; type=int; label=Products Page ID
productsPage =
}
}
Now the problem is that even though I am 100% sure Typoscript is properly included into page where extension is loaded, the variables $this->settings['productsPage'] and in FLUID {settings.productsPage} doesn't work. I cleared whole cache and even tried removing whole typo3temp folder and it still doesn't work. I also tried debugging $this object and it says settings => NULL.
Oh the productsPage is entered in Default Root template under "SETUP" and when browsing Typoscript objects (in administration) I can see the setting set just fine. So I don't think I have invalid TypoScript.
If you have four plugins you have to set this Typoscript settings for each plugin. If your Typoscript above is included correctly, "settings" will only be accessible for the plugin "basket".
Another thing: The comments in your Typoscript seems like those settings are Typoscript constants and not Typoscript setup. In the setup you have to pass those constants to the plugin configuration too. Example:
plugin.tx_extname_basket {
settings {
productsPage = {$plugin.tx_extname_basket.settings.productsPage}
}
}
You also have to pass the other constants for templates etc. to the setup.

Is there a way to force Yii2 to reload module assets on every request?

My website is divided into separate modules. Every module has it's own specific css or js files.
Yii's assetManager creates a folder when I first open a page that uses my assets.
Unfortunately if I change something in my files Yii 1.x does not reload my css or js files.
I have to manually delete the web/assets folder. It is really annoying when you are developing the app.
This works when I add a module to the backend folder, but not when I'm creating a module in the vendor folder with my own namespace.
In Yii2 you can append a timestamp to the URLs of assets like this...
return [
// ...
'components' => [
'assetManager' => [
'appendTimestamp' => true,
],
],
];
This won't force the assets to reload on every request but whenever an asset file is changed the URL will change because of the timestamp & that will force the asset to be re-published.
You can set forceCopy = true.
class Assets extends AssetBundle{
public function init()
{
parent::init();
$this->publishOptions['forceCopy'] = true;
}
}
With respect to Yii1.x With assetManager you can do this by setting 'forceCopy' attribute to true in your config file
... copy the asset files and directories even if they already published
before. This property is used only during development stage
See forceCopy documentation here for more info.
Alternatively you can use linkAssets which will not copy the files but create an soft link between your asset files and yours assets directory. You cannot of course use both.
For the second part of the question I am assuming this is in Yii 2.x, you are supposed to use AssetBundles, you can register any namespace bundle from anywhere, you simply register it in the view with some like this
use vendor\myVendorName\myPackageName\assets\AppAsset;
AppAsset::register($this);

set view suffix for view files in zend framework 2

The default zend framework 2 configuration relies on phtml files for view rendering. However, for security reasons I want to change that to php.
From this link I understand that I need to create a custom view helper in order to do that or is there a setting I can change to change the suffix from phtml to php and how is this done exactly?
Update: I got it working, but not the way I want. If possible I would like to get the answer from guessimtoolate working. So I prefer something like this in my module.config.php:
'view_manager' => array(
'default_suffix' => 'php',
//etc...
)
If my memory serves my well, you can define that in default_suffix key in your module's configuration file under view_manager, e.g.:
return array(
// ...
'view_manager' => array(
'default_template_suffix' => 'php',
// ...
),
// ...
);
This should make template file resolvers to look for .php files instead of .phtml.
Not entirely sure how's that an improvement, but it can be done.
UPDATE:
Sorry, I've wrote the wrong configuration key name -- it should be default_template_suffix and not default_suffix. It is used, e.g.: in Zend\Mvc\Service\ViewTemplatePathStackFactory where path stack resolvers are born :).
Try this in your module.php:
//module.php
public function onBootstrap(MvcEvent $e)
{
$application = $e->getApplication();
$sm = $application->getServiceManager();
$sm->get('ViewTemplatePathStack')->setDefaultSuffix('php');
}
Then change all .phtml files to .php in your project.
In your Application module, the Module.php file:
public function onBootstrap($e)
{
$app = $e->getApplication();
$sl = $app->getServiceManager();
$resolver = $sl->get('ViewTemplatePathStack');
$resolver->setDefaultSuffix('php');
}
What happens here, is during bootstrap you grab the path stack and sets the suffix on the resolver.

How do I get Zend Framework to use 'module specific' configurations?

Reading the section Zend_Application_Resource_Modules in the docs here:
http://framework.zend.com/manual/1.10/en/zend.application.available-resources.html
I noticed this:
You can specify module-specific configuration using the module name as a prefix or sub-section in your configuration file.
using this:
[production]
news.resources.db.adapter = "pdo_mysql"
news.resources.db.params.host = "localhost"
news.resources.db.params.username = "webuser"
news.resources.db.params.password = "XXXXXXX"
news.resources.db.params.dbname = "news"
To me this is a good idea. But, when I simply add these prefixes to certain things I want to be specific to my modules, nothing changes.
So my question is: How do I tell Zend Framework to actually use these module specific prefixes?
I use the following implementation of modules in Zend. It allows you to use "module-specific" configuration.
application/config/config.ini
-----------------------------
[production]
resources.modules[] =
By doing this, you're telling Zend_Application that you want to use the Modules Bootstrap Resource plugin. The Modules plugin will load a separate bootsrap class for each of your modules, excluding the default module. Therefore, you need to create a new bootstrap class for your second module.
application/modules/news/Bootstrap.php
-----------------------------
class News_Bootstrap extends Zend_Application_Module_Bootstrap {
//---------------------------------------
// Automatically load our resources
//
// NOTE: You don't have to add this, its
// just and example to show that you
// can customize the bootstrap
// process just for this module.
public function _initModuleResourceAutoloader(){
$this->getResourceLoader()->addResourceTypes(array(
'modelResource' => array(
'path' => 'models/resources',
'namespace' => 'Resource'
)
));
}
}
This "News_Bootstrap" class will now be loaded and executed during the bootstrap process.
The naming convention for this file is important as the Modules Resource plugin needs to be able to find the class. Note that you must name the file Bootstrap.php.
Finally, you'll notice that you're subclassing the Zend_Application_Module_Bootstrap rather than Zend_Application_Bootstrap_Bootstrap like you do in the main bootstrap.
Now, your module-specific configuration should work:
[production]
news.resources.db.adapter = "pdo_mysql"
news.resources.db.params.host = "localhost"
news.resources.db.params.username = "webuser"
news.resources.db.params.password = "XXXXXXX"
news.resources.db.params.dbname = "news"

Categories