i have a bare bones zf2 application and i have 2 modules (Users and Album).
They both have their own layouts but i want to use the layout from Album for the Users, just to keep them a bit more consistent.
Im not sure what is the best way to delegate what layout a module should use.. from the controller __contruct, or on each individual action or in the module.config.php.
maybe here:
'template_map' => array(
'layout/top_nav' => __DIR__ . '/../view/layout/top_nav.phtml',
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
^^ probably i should set this path to the layout i want to use ^^
'posts/index/index' => __DIR__ . '/../view/posts/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
any ideas? maybe the best practices?
thanks
edit: i just did this and it worked:
'layout/layout' => __DIR__ . '/../../album /view/layout/layout.phtml',
but i'm still not sure if this is best practice.
maybe i can setup multiple template_map arrays and use them in the User controller, in my case
Edit: removed my own bullshit, just see the alternative approach :) That works
Alternative approach
Evan Coury also made the effor to have the Layout configuration globally available. This is especially true for single developers who won't make their modules public, ever. You will find his EdpModuleLayouts Module right here.
Using that module switching layouts becomes even simpler like the following:
<?php
array(
'module_layouts' => array(
'ModuleName' => 'layout/some-layout',
),
);
Hope it helps.
Related
I'm learning ZF2 and I am constructing a web site to make sure that I understand the new concepts of ZF2, but I was wondering if there is a way to specify a template for the error pages in the application module.
Thanks
There some pre-set configuration options within the module.config.php like:
...
'view_manager' => array(
'not_found_template' => 'error/404',
'exception_template' => 'error/exception',
'template_map' => array(
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/exception' => __DIR__ . '/../view/error/exception.phtml',
),
),
...
After creating the Folder and the Files you should be good to go.
I have stored a third party php library in /vendor/library folder. Now i need to import it to my Zend app and use it inside controller action.
require_once ('/vendor/library/client.php');
Is this correct ? Or there is other way to to handle this ?
Use the ZF autoloader, then forget about include/require.
http://framework.zend.com/manual/1.12/en/zend.loader.autoloader.html
It means though that your class names and file names have to follow their naming conventions - which may be more trouble than it is worth.
But if you are developing your own library to work within ZF, then it is a good idea.
Adding a Composer ready 3rd party library to a ZF2 instance
The correct way to add a 3rd party library is to use Composer.
E. g. if you wish to add ZfcUser to your Zend Framework 2 application use the following command:
composer require zf-commons/zfc-user:dev-master
This will download the code from github and you just need to add the module name to your: /config/application.config.php.
Adding other 3rd party library to a ZF2 instance
If your 3rd party library is not Composer ready, you can add it to your Zend Framework 2 instance by creating a Module for it.
Step 1
/vendor/MyModule/Module.php
<?php
namespace MyModule;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
class Module implements AutoloaderProviderInterface
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
What this basically provides is a way for you to register your 3rd party code within a file called autoload_classmap.php:
Step 2
/vendor/MyModule/autoload_classmap.php
<?php
return array(
'MyModule\VendorLibrary' => __DIR__ . '/src/MyModule/VendorLibrary.php',
);
Step 3
Your 3rd party code should reside in:
/vendor/MyModule/src/MyModule/VendorLibrary.php and could read something like this:
<?php
namespace MyModule;
class VendorLibrary
{
public function sayHi($name)
{
return "Hi there, $name!";
}
// your 3rd party code ...
}
Step 4
Add your new module to application.config.php:
/config/application.config.php
<?php
return array(
'modules' => array(
// your other modules here ...
'MyModule'
),
'module_listener_options' => array(
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
'module_paths' => array(
'./module',
'./vendor',
),
),
);
Usage
In your Controller you now use your vendor class like:
$vendor = new \MyModule\VendorLibrary();
$hi = $vendor->sayHi('John');
While it is a lot easier to use require_once(), it is not advisable because:
it does not provide predictability and structure of your class hierarchy and location
you also need to take care of include paths and make sure require_once is present in all controllers that need the 3rd party features
it does not allow for overriding classes (Magento-style)
etc.
Hope this helps!
I've been able to load a view template and use it to create the body of an email message. The code is similar to the answer here:
How to render a mail template with layout in ZF2?
But now I'm looking to take this code and move it into a module that helps the rest of my application send emails. I'm thinking I would like to make it as easy/transparent as possible to use views for all emails.
So the basic question is, how can I setup the code to accept the information it needs to render a template and send the email?
I already have my transport information held inside the service locator, and sending email works fine. My primary concern is mostly the messy code needed for the template resolver:
$view = new PhpRenderer();
$resolver = new TemplateMapResolver();
$resolver->setMap(array(
'mail' => __DIR__ . '/../../../view/communication/email/new-project.phtml'
));
$view->setResolver($resolver);
I am alright with having all the *.phtml for emails held inside the new module. There's no need to send adhoc emails out of the application (we use communications internal to the application).
Is there a way to use the module.config.php 'view_manager' => 'template_map' and bypass the need to create a new resolver()? In that case I could setup the email code to accept the named template that should be in that map.
'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',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
You simply have to access the default viewrenderer via the ServiceManager.
$viewRenderer = $this->getServiceLocator()->get('viewrenderer');
$mailView = new ViewModel();
$mailView->setTemplate('my-namespace/controller/mailtemplate.phtml');
$mailView->setVariables(array(
//k=>v paired data
));
$renderedOutput = $viewRenderer->render($mailView);
$mail->setBody($renderedOutput);
And that's pretty much it. Obviously though the concrete mail handling is stripped from this example, as you're mostly looking at another problem, given your description.
There are different modules and all of them returns ViewModel in the actions. But somehow, ViewModel acting weird a bit in one of the modules.
I am saying;
$view = new ViewModel(array('data' => $someContent));
$view->setTemplate('a valid path to template');
return $view;
and getting an empty page.
If I put an exit() statement at the end of related template like
<!DOCTYPE html>
<html>
...
</html>
<?php exit(); ?>
I can get the expected output because script ends there but I lost the output otherwise.
If I say *var_dump($view)*, I can see that the $view is an instance of Zend\View\Model\ViewModel.
There is no error, just an empty output and even the notice warnings are visible. So, it doesn't throw any exception, error, warning, notice etc.
To remind that again, it just happens in a specific module but that module are not different the others actually.
I am not a ZF guru and I am working on someone else's codes, so please give me a start point to able to find that problem.
Thanks in advance.
edit : I have an extra info;
It works if I use JsonModel instead of ViewModel and as you may know, JsonModel extends the ViewModel.
Since you have not posted your controller action properly , this is the guess what I could do on your problem .
In Zend framework 2 there are various types of controllers from which you will be extending your controllers with in your modules .
for example in case if you extend your controller from AbstractActionController your view will be returned properly .
So the problem here is your other modules have controllers extending AbstractActionController . This module which is not returning your view properly might not be extending it . Instead it might be extending other controllers such as restfulcontrollers
You should also check in module.php file of your module to check whether you have any strategies eg json strategy applied on bootstrap for this module from module.config.php .
eg.
return array(
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy',
),
),
)
Also you have check your module.config.php file whether you have proper specification for your viewmanager to your template .
eg .
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
Hope this helps .
I need 2 different template maps in ZF2 , one for admin and oen for front-end, currently from what I can see ZF2 merges the 2 module.config.php files that are used in the 2 modules I configured, and causes the template map I need to set for the admin, to be loaded in front module also.
the /Application module.config.php
...
'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',
'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',
),
...
the /admin module.config.php
...
'view_manager' => array(
'template_path_stack' => array(
'admin' => __DIR__ . '/../view',
),
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
),
),
...
what should I modify so that i can load separate "view_manager" arrays for the 2 separate modules ?
It would be great if you can explain why you are trying to achieve this. As i can see you are trying to have a different layout for admin. Maybe you want to take a look at this module which can already do what you are trying https://github.com/zf-commons/zfcadmin. This module has a layut setup for the admin route.
I too had this problem. I took the approach which is proposed in the below module
https://github.com/EvanDotPro/EdpModuleLayouts
I'm new to ZF2 and I too was looking for an answer on how to have a completely different template for a dashboard, admin and front end.
I used EdpModuleLayouts as suggested here and in many other posts. This solved one aspect of the problem. The layout. I was now able to provide different layouts for the same template which would work well if I were using the same template or wanted to prove a different layout for say forgotten password, registration or a login. But I didn't. I needed a whole different set of folders, css files etc. At this point I could have just nested all templates in to a template folder and pointed the links in the layout files to the appropriate folders. But I didn't want this either.
I also included the zfc-admin module into my app which gave me a clue as to the other aspect which is to provide a different source directly for files. (Uninstalled afterward)
So adding by adding the following to my module_name/config/module.config.php
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view'
),
),
Enabling EdpModuleLayouts in application.config.php and adding the code below to the Application module.config.php
'module_layouts' => array(
'Application' => 'layout/layout',
'Dashboard' => 'layout/dashboard',
'Admin' => 'layout/admin',
),
This is probably not the best way to do it but it worked. The only issue I could really see with doing it this way is that EdpModuleLayouts wants to pull all the layouts from the Application/view/layout folder. It did however allow me to keep all my module template files in the view section of the module being worked on.