Find out how a template should be referenced in Symfony 2.7 - php

I have created a custom template that I am trying to render from a controller. I have placed the template in src/MyCompany/AppBundle/Contact/contact.html.twig and am using this line to try to bring it in:
return $this->render('AppBundle:Contact:contact.html.twig', array(
'form' => $form->createView()
));
But I get this InvalidArgumentException when loading the controller:
Unable to find template "AppBundle:Contact:contact.html.twig" (looked
into: /usr/src/app/app/Resources/views,
/usr/src/app/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form,
/usr/src/app/vendor/knplabs/knp-menu/src/Knp/Menu/Resources/views).
Is there a simple way to find out how I should be referencing this template?

By default Symfony will look in the Resources/views directories of your bundles to find the templates. If you need a custom path like src/MyCompany/AppBundle/Contact you'll have to manually register it in twig configuration in your config.yml:
twig:
# ...
paths:
'%kernel.root_dir%/src/MyCompany/AppBundle/Contact': contact_path
and then use it like this:
return $this->render('contact_path:contact.html.twig', array(
'form' => $form->createView()
));
Documentation here

Related

How to move Bundle/Resources folder to a subfolder in Symfony?

I'd like to structure a Symfony3 Bundle into submodules.
For this I would like to move the Bundle/Resources folder (with views, config and public) along with the controller classes into a subfolder.
Example with a DemoBundle and the Messages module. The directory should be like this:
+ DemoBundle
+ Directory
+ Posts
+ Messages
+ Controller
+ MessageController.php
+ Resources
+ config
+ public
+ views
+ listing.html.twig
I could move the Controller by making an entry to the routing.yml file like this:
demo-messages:
resource: "#DemoBundle/Messages/Controller/"
type: annotation
prefix: /
The Controller now looks like this:
class MessageController extends Controller {
/**
* #Route("/messsages", name="Message")
*/
public function listingAction(Request $request) {
return $this->render('listing.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
]);
}
}
When I now navigate to this route, I get an error: "Unable to find template". The error says it is still looking in /demo/Resources/views instead of /demo/messages/Resources/views.
Question: Can I somehow tell symfony to look in the folder /demo/messages/Resources/views? Is that possible at all? Or is my template addressing in $this->render(...) wrong?
So far tried the following versions for the template reference:
return $this->render('messages/listing.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
]);
Effect: Error: Template not found
~~~
return $this->render('#DemoBundle/Messages/Resources/views/listing.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
]);
Works!
The reason I chose this structure over a Bundle for each submodule is that i would like to encapsulate the user interface in this Bundle while i'd like to organize the admin interface in the AdminBundle.
Cerads solution with namespaced template references helped. The following code worked:
return $this->render('#DemoBundle/Messages/Resources/views/listing.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
]);
Drawbacks with this workaround are that the short hand template reference is not possible any more and that the copying of the assets (CSS, JS, etc.) doesn't work with php bin/console assets:install

FuelPHP and Smarty - Variables not working

Not sure if Smarty is even loading but its showing {$title} and {$username} directly on the page and not using what's set as the variable.
I added into composer.json
"smarty/smarty": "*"
I run php composer.phar update and also install:
I'm loading in the config.php file the parser as per
'packages' => array(
'orm',
'auth',
'parser',
),
In my controller dashboard.php
public function action_index()
{
$data = [
'bodyclass' => "dashboard",
'title' => "Dashboard",
'username' => "James"
];
$view = Response::forge(View::forge('dashboard/index.tpl', $data));
$this->template->subnav = array('dashboard'=> 'active' );
$this->template->content = $view;
}
and in my index.tpl file I have
{$title} {$username}
It's just for testing, however does not seem to be working.
FuelPHP's Parser package handles the rendering of views using template engines.
As you've already done, you must first enable the Parser package in fuel/app/config.php by making sure the parser package is added to always_load
'always_load' => array(
'packages' => array(
'parser',
),
),
Parser uses the file's extension to determine which parser engine to use. In your case your file, dashboard/index.tpl uses a typical smarty extension .tpl, however FuelPHP doesn't have a template registered for that extension.
FuelPHP uses .smarty by default.
So, you have 2 options.
Change your template's file extension, adhering to the FuelPHP default
Change FuelPHP's configuration to use Smarty for .tpl files
Fortunately both are easy. If you choose to go with option 2, check out the default configuration definition.
You can override the defaults using a config file located at fuel/app/config/parser.php
return array(
// Overrides default smarty extension
'extensions' => array(
'tpl' => 'View_Smarty',
)
);

ZF2 'unable to render template' when shifting module names in the array in app config

Good day.
I've just started learning ZF2, replicated the Album example step-by-step, and then decided to make it a bit more interesting by adding user registration, and then make the two work together in some way, so i added a new 'Auth' module.
So, when i only had one module in the module list (aside from the Application module) in application.config.php, it was all fine, but when i added the Auth module to the list like so:
'modules' => array('Application', 'Album','Auth',)
i got the following error when trying to access any views from the album module which was working absolutely fine prior to this change:
Zend\View\Renderer\PhpRenderer::render: Unable to render template "album/album/index"; resolver could not resolve to a file
But when i changed the order in which the modules are presented in this array like so:
'modules' => array('Application', 'Auth','Album',)
not a single view (and it has only one) from the Auth module could be rendered, while the Album module was fine.
Zend\View\Renderer\PhpRenderer::render: Unable to render template "auth/user/index"; resolver could not resolve to a file
Both of these views exist at these locations, but the renderer doesn't see them for some reason.
You can see the project's contents here.
Thank you for any tips in advance.
Looks like you copy pasted the the view manager config for Auth module.config.php.
This should be auth rather than album for your templates to work correctly.
'view_manager' => array(
'template_path_stack' => array(
'auth' => __DIR__ . '/../view',
),
),

Symfony2 components, loading controllers

I am using routing component to load controllers, and if i use just
$routes->add(
'index',
new Route('/', array('_controller' => 'indexAction'))
);
my "project" perfectly loads indexAction function, but if i try something like this
$routes->add(
'index',
new Route('/', array('_controller' => 'Test::indexAction'))
);
it says
Uncaught exception 'InvalidArgumentException' with message 'Class "Test" does not exist.'
But i cant find where must be my controllers, or how they must be included to be loaded successfully.
If this helps, at this moment i am using composer autoload with PSR-0 standart.
Like its said on the Symfony doc about routing, you have to
name your controller with this pattern :
bundle:controller:action
"Full" path solved the problem
new Route('/', array('_controller' => 'Levelup\\Controller\\Test::indexAction'))
Test::indexAction changed to Levelup\Controller\Test::indexAction

Views/Resources location for Silex Twig Library

Normally, for a Silex project, I would have top-level directories like:
- app/
- views/
- src/
- vendor/
- web/
Now, some of my classes may call $app['twig']->render(...) and it will pull out a view from the app/views folder.
If I extract a library to be more reusable, across multiple projects, where should I keep its view files, and how do I instruct Twig to look there?
The same question applies to graphics/stylesheets, etc which I would normally put in web/.
Surely they have to be within vendor/my-lib somewhere to allow Composer to cleanly install the files? Is there a common/best-practice way to do this?
Update
For reference, here's what I ended up doing:
<?php
// in my \Silex\ServiceProviderInterface ...
/**
* #var \Twig_Environment $twig
*/
$twig = $app['twig'];
// Add the paths to our twig templates here
$fsLoader = new \Twig_Loader_Filesystem(array(
__DIR__.'/views/'
));
$twig->setLoader(new \Twig_Loader_Chain(array($twig->getLoader(), $fsLoader)));
Thanks.
I store the views under src/{Library}/{Class}/View/
I set the base path of Twig to the src
$app->register(new TwigServiceProvider(), array(
'twig.path' => array(
__DIR__ . '/../src/{Library}/'
),
'twig.options' => array('cache' => false, 'strict_variables' => true)
));
and when calling render I pass in the path from that point
$app['twig']->render('{Class}/View/{twigfile}.html.twig',$data);

Categories