I'm trying to load a different view depending on the value taken from a Regex route, but I can't get the ViewModel to load the template
public function viewAction()
{
$page = $this->params()->fromRoute()["page"];
$view = new ViewModel();
$view->setTemplate('module/Base/view/base/index/$page');
return $view;
}
I'm following the conventional module setup:
Base
|- config
| |- module.config.php
|- src
| |- Base
| |- Controller
| |- IndexController.php
|- view
|- base
| |- index
| |- index.phtml
| |- other.phtml
|- layout
And my view_manager configuration is:
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
I've tried all sort of values in the path passed to setTemplate, but I just keep getting the application error message, but no error log or details (that may be because I haven't figured out displaying errors properly). I have confirmed that $page is getting the name of the template correctly from the URL, and the template is in the correct directory.
So, where does ViewModel start looking for templates?
I've tried:
$view->setTemplate('$page.phtml');
$view->setTemplate('$page');
$view->setTemplate('base/index/$page.phtml');
$view->setTemplate('base/index/$page');
$view->setTemplate('module/Base/view/base/index/$page.phtml');
$view->setTemplate('module/Base/view/base/index/$page');
Each module that requires view scripts should have a view_manager key in module.config.php
You have two choices when registering view scripts.
'view_manager' => [
'template_map' => [
'module-name/foo/bar' => __DIR__ . '/../view/foo/bar.phtml',
'custom_view_template_name' => __DIR__ . '/../view/some/other/path/bar.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
],
Template Path Stack
This represents a collection (stack) of paths that the view resolver will try to find paths from.
The view scripts that you set on the view models in the controller would then be relative to this directory path. This option saves you time by 'automatically' resolving view script paths using a common naming convention.
For example, if you have FooModule and the file FooModule/view/foo-module/index/index.phtml the template path that should be used in the controller would be foo-module/index/index.
Template Map
A one to one mapping of template name to template path. This means the template path is exactly the same as the array key.
You should try to favor this method as using the template_path_stack incurs a slight performance hit as the view scripts need to be resolved at runtime.
I am using it like this:
after the view folder inside your module add the path. So I assume yours is
view->setTemplate('base/index/$page');
This should do the trick.
Related
In an Apigility driven Zend Framework 2 application wenn a database adapter is created (over the Apigility Admin UI), its settings by default get saved in /config/autoload/global.php
return array(
'db' => array(
'adapters' => array(
...
'DbAdapter_FooBar' => array(),
...
),
),
...
);
and in /config/autoload/local.php
return array(
'db' => array(
'adapters' => array(
...
'DbAdapter_FooBar' => array(
'charset' => 'UTF-8',
'database' => 'asdf',
'driver' => 'PDO_Mysql',
'hostname' => 'asdf',
'username' => 'asdf',
'password' => 'asdf',
'port' => '1234',
'driver_options' => array(
1002 => 'SET NAMES \'UTF8\'',
),
),
...
),
),
...
);
In the application I'm working on the config files structure differs from the ZF2 standard, e.g. there are separate config files for the database settings: /config/autoload/mydb.global.php and /config/autoload/mydb.local.php.
(How) Can Apigility be configured in the way, that the database adapters settings get stored in custom config files? How/where to set these files?
Configuration for various components can be provided in multiple places, but all configuration is merged recursively into one large configuration file by the Zend\Stdlib\ArrayUtils::merge() method. Because configurations are merged recursively, the order that they are added to the merged configuration array is really important to avoid unexpected overwriting.
Configurations are merged in the following order:
The array returned by the module’s getConfig() method
config/autoload/*.global.php — global autoload files
config/autoload/*.local.php — local autoload files
The methods described by the Feature interface — get*Config()
In ZF2 we can set our templates in the Application controller:
'layout/layout' => __DIR__ . '/../theme/metronic/view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../theme/metronic/view/application/index/index.phtml',
'error/404' => __DIR__ . '/../theme/metronic/view/error/404.phtml',
'error/index' => __DIR__ . '/../theme/metronic/view/error/index.phtml',
This is really useful in terms of code consistency.
My particular template is an administration theme and the login page is completely different from the general layout pages. Obviously I do not want the admin side menus to appear in the login page...
The general pages look like this: http://www.keenthemes.com/preview/index.php?theme=metronic_admin&page=index.html
And the login page looks like this: http://www.keenthemes.com/preview/index.php?theme=metronic_admin&page=index.html
I have written my Login module however I have no idea how to override the general layout/layout page.
I am still coming to grips with ZF2 routing and I assume all I need to do is enter the correct route to the login template... The other alternative is to put some code in the layout/layout template.phtml file to check if the login url has been accessed and to serve the alternative template. This seems a little messy considering the advanced routing that comes with ZF2.
Am I missing something here?
I have found the answer and it is relatively simple to install although the documentation is not straightforward.
Thank you to: http://www.webtrafficexchange.com/zf2-configure-layout-each-module-edpmodulelayouts
Basic steps are follows:
Clone git clone https://github.com/EvanDotPro/EdpModuleLayouts.git to your Vendor folder
Enable in application.config.php:
'modules' => array(
'Application',
'EdpModuleLayouts'
),
In your application/module.config.php file, add the layouts. This is mine:
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'login/layout' => __DIR__ . '/../view/login/login.phtml',
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
//Use this to set a custom layout
'module_layouts' => array(
'Login' => 'login/layout',
),
I thought I would add an update to my previous answer. For a simple application EdpModuleLayouts is perfect however there is even a simpler way to change templates that I discovered after the previous answer.
Create a template map as per usual in your Applications module or module of choice:
'template_map' => array(
'login/layout' => __DIR__ . '/../view/login/login.phtml',
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
Then in the action of the controller, simply use:
$this->layout('login/layout');
This is not a solution if you are attempting to change the template of a .vendor controller action under composer control.
I'm going through the zend 2 getting started tutorial and I hit a wall. I am at the point in the tutorial where my action controller loads a view via the indexAction():
public function indexAction() {
return new ViewModel(array(
//$albums inside index.phtml will contain data from this method
'albums' => $this->getAlbumTable()->fetchAll()
));
}
But when loading the page I see this error:
Zend\View\Renderer\PhpRenderer::render: Unable to render template "album/album/index"; resolver could not resolve to a file
At this point I realized I don't know what the hell is happening. I don't even know where to begin troubleshooting this error. Before I scan all of the files for typos I'd really like to understand how this error can occur.
here is my modul.config.php:
<?php
return array(
'controllers' => array(
'invokables' => array(
'Album\Controller\Album' =>
'Album\Controller\AlbumController',
),
),
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'ablum' => __DIR__ . '/../view',
),
),
);
The error "Unable to render template "album/album/index" means that you have to add the index.phtml file under the /album/album directory under the 'Album' module's view directory. The index.phtml view template file is used for rendering the view for the index action of the AlbumController controller of the Album module. Because this file seems to be missing, the view template resolver couldn't find it.
In Zend Framework 2, you implement a view as a template file, which is a file
having .phtml extension ("phtml" stands for PHP+HTML). View templates have such
a name because they usually contain HTML code mixed with PHP code snippets used
for rendering the web pages. Views typically live inside of the view subdirectory of the module.
For beginner, I would recommend to read the Using Zend Framework 2 book. With this e-Book, you can save your time and efforts learning ZF2.
Also, the path is case sensitive i.e. it should be all be in lowercase album/index/index both folders' name and index.phtml else phpRenderer will not be able to trace the view file and render it.
You can also check if you have the following in your module.config.php
'view_manager' => [
'template_path_stack' => [
__DIR__ . '/../view',
],
],
Good evening,
I want to add zend/translate to my project to show my webside in several languages. But there doesn't work anything. Here are the steps I done already:
In the module.config.php I looked if the translator is initialized:
...
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
...
'translator' => array(
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
...
In the Module.php in the Bootstrap I set the DefaultTranslator:
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
\Locale::setDefault('de_DE');
\Zend\Validator\AbstractValidator::setDefaultTranslator(
$e->getApplication()
->getServiceManager()
->get('translator')
);
}
But when I reload my webside there is a error like this:
Catchable fatal error: Argument 1 passed to Zend\Validator\AbstractValidator::setDefaultTranslator() must be an instance of Zend\Validator\Translator\TranslatorInterface, instance of Zend\I18n\Translator\Translator given, called in C:\xampp\htdocs\pimp\module\Application\Module.php on line 28 and defined in C:\xampp\htdocs\pimp\vendor\zendframework\zendframework\library\Zend\Validator\AbstractValidator.php on line 472
I think there is something I've forgotten..
Can someone help me?
Thanks.
There is a odd part in Zend i18n that Zend\I18n\Translator\Translator is not compatible with other components. The Mvc Translator binds the Translator to the other parts. The Zend\Mvc\I18n\Translator extends the "normal" translator and then it implements the translator interface requested by the Zend\Validator component.
So, create the Mvc Translator by using the MVC translator factory. Replace Zend\I18n\Translator\TranslatorServiceFactory with Zend\Mvc\Service\TranslatorServiceFactory.
this is simple tutorial
http://samminds.com/2012/09/zend-framework-2-translate-i18n-locale/
http://www.poedit.net/
but i have
,'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'translate',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
in module.config.php and a php file that all keys exist on it for example
<?php
/*
* General keys
*/
$this->translate('projectname');
$this->translate('login');
$this->translate('logout');
$this->translate('pages');
$this->translate('contents');
$this->translate('ourposition');
$this->translate('search_pleace');
$this->translate('contactform');
$this->translate('pleaseuploadresume');
?>
in poedit i only set path of this file. (help to better management) and on Catalog properties-> sources keywords translate should be exist ( and of course be better one) . any where i want show message . i write
echo $this->translate('key');
I was previously using a downloaded version of Zend Framework 2 and was basically able to do something like this:
// Set include paths (add Zend to the path)
set_include_path(get_include_path() . PATH_SEPARATOR . $__CONFIG['zendPath']);
// Setup the Zend Autoloader
require_once('library\Zend\Loader\StandardAutoloader.php');
$autoLoader = new StandardAutoloader(array(
'namespaces' => array(
'Zend' => $__CONFIG['zendPath'] . '/library/Zend'
)
));
This works because all Zend packages are inside the library folder. I now wanted to use composer to load only the Zend packages I need. The problem I'm running into is that the packages get arranged in the following way:
zendframework/zend-cache/Zend/...
zendframework/zend-loader/Zend/...
zendframework/zend-validator/Zend/...
etc.
I tried having separate namespace declarations in the StandardAutoloader like this:
$autoLoader = new StandardAutoloader(array(
'namespaces' => array(
'Zend\Cache' => $__CONFIG['zendPath'] . '/library/zend-cache/Zend/Cache',
'Zend\Loader' => $__CONFIG['zendPath'] . '/library/zend-loader/Zend/Loader',
'Zend\Validator' => $__CONFIG['zendPath'] . '/library/zend-validator/Zend/Validator'
)
));
That doesn't work. Am assuming the namespace probably can't have the backslashes in it? is there any way to make this work? Preferably without having to define each individual package.
You just have to fix the paths:
$libs = $__CONFIG['zendPath'];
$autoLoader = new StandardAutoloader(array(
'namespaces' => array(
'Zend\Cache' => $libs . '/library/zend-cache/Zend',
'Zend\Loader' => $libs . '/library/zend-loader/Zend',
'Zend\Validator' => $libs . '/library/zend-validator/Zend',
)
));
That should do the trick (it's un-tested, so I'm not sure about the trailing Zend
Let it autoload Zend for you:
$autoLoader = new StandardAutoloader(array(
'autoregister_zf' => true, // Auto load Zend Namespace..
'namespaces' => array(
// extra namespaces
)
));