I am creating a new Twig Environment object inside a custom class, that class is being rendered from an existing twig file. I am trying to render a form in my twig file which is being rendered from my custom class, however in this new Twig_Environment object form functions are not available, i have tried adding existing form extension from symfony's own twig object to my new twig object, that is not working either.
$path = 'some/directory'; // just simplifying here
$loader = new \Twig_Loader_Filesystem( $path );
$twig = new \Twig_Environment($loader, array(
'cache' => __DIR__.'/../../../../../../app/cache/',
));
$tmpl = $twig->loadTemplate('EmailUs.html.twig');
$twig->addExtension( new \Symfony\Bridge\Twig\Extension\FormExtension( $this->pageObj->getContainer()->get('twig.form.renderer') ) );
$response = new Response();
$response->setContent($tmpl);
return $response;
The error i get is
"The function "form_start" does not exist in EmailUs.html.twig at line
8"
I was using symfony's own twig object to render the response but that was giving me the same error. Can you help pls? I am using Symfony 2.3.4
Form functions are available if i render a normal controller, they dont work fine if i create a custom twig object.
I have solved it this way:
$loader = $pageFunctions->getContainer()->get('twig.loader');
$loader->addPath( $path );
$twig = new \Twig_Environment($loader, array(
'cache' => __DIR__.'/../../../../../../app/cache/myTwig',
));
foreach( $this->twig->getExtensions() as $ext ) {
$twig->addExtension( $ext );
}
$tmpl = $twig->loadTemplate('EmailUs.html.twig');
$rendered = $tmpl->display( array('control' => $this,
'functions' => $pageFunctions,
'params' => $params,
'email_form'=>$form->createView() ) );
return $rendered;
Here's my working code (executed inside a controller action):
$path = __DIR__.'/../Resources/views/'; /* twig loader path */
$loader = new \Twig_Loader_Filesystem($path);
$twig = new \Twig_Environment($loader);
$twig->addExtension( new \Symfony\Bridge\Twig\Extension\FormExtension($this->get('twig.form.renderer')));
$tmpl = $twig->loadTemplate('test.html.twig');
return new Response($tmpl->render(array()));
I've mainly moved the addExtension call before the loadTemplate one (otherwise extensions would have been already initialized).
Related
What does Container->get('route') method returns and why
It is used in twig extension with slim
The Slim Twig extension requires the router (not the route) instance for the custom template functions like path_for() and base_url().
Example:
// Register Twig View helper
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('path/to/templates', [
'cache' => 'path/to/cache'
]);
// Instantiate and add Slim specific extension
$router = $c->get('router');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$view->addExtension(new \Slim\Views\TwigExtension($router, $uri));
return $view;
};
Please read the slimphp/Twig-View documentation.
Per http://twig.sensiolabs.org/doc/api.html#using-extensions:
When creating a new Twig_Environment instance, you can pass an array
of options as the constructor second argument:
$twig = new Twig_Environment($loader, array('debug' => true));
How would this be implemented when used with Slim? My attempt is below, however, {{ dump(foo) }} results in an Unknown "dump" function in "forms.html" at line 35. error. I have tried adding the script on the Twig website, however, I don't know what to use for $loader and where to insert $twig.
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('../application/templates', [
//'cache' => 'path/to/cache' // See auto_reload option
'debug' => true,
'strict_variables'=> true
]);
$view->addExtension(new \Slim\Views\TwigExtension(
$c['router'],
$c['request']->getUri()
));
return $view;
};
I'm writing my own PHP framework built on top of Symfony components as a learning exercise. I followed the tutorial found at http://symfony.com/doc/current/create_framework/index.html to create my framework.
I'd now like to wire up my routes against my controllers using annotations. I currently have the following code to setup the routing:
// Create the route collection
$routes = new RouteCollection();
$routes->add('home', new Route('/{slug}', [
'slug' => '',
'_controller' => 'Controllers\HomeController::index',
]));
// Create a context using the current request
$context = new RequestContext();
$context->fromRequest($request);
// Create the url matcher
$matcher = new UrlMatcher($routes, $context);
// Try to get a matching route for the request
$request->attributes->add($matcher->match($request->getPathInfo()));
I have come across the following class to load the annotations but I'm not sure how to use it:
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php
I'd appreciate it if someone could help.
Thanks
I've finally managed to get this working. First I changed where I included the autoload.php file to the following:
use Doctrine\Common\Annotations\AnnotationRegistry;
$loader = require __DIR__ . '/../vendor/autoload.php';
AnnotationRegistry::registerLoader([$loader, 'loadClass']);
Then I changed the routes collection bit (in the question) to:
$reader = new AnnotationReader();
$locator = new FileLocator();
$annotationLoader = new AnnotatedRouteControllerLoader($reader);
$loader = new AnnotationDirectoryLoader($locator, $annotationLoader);
$routes = $loader->load(__DIR__ . '/../Controllers'); // Path to the app's controllers
Here's the code for the AnnotatedRouteControllerLoader:
class AnnotatedRouteControllerLoader extends AnnotationClassLoader {
protected function configureRoute(Route $route, ReflectionClass $class, ReflectionMethod $method, $annot) {
$route->setDefault('_controller', $class->getName() . '::' . $method->getName());
}
}
This has been taken from https://github.com/sensiolabs/SensioFrameworkExtraBundle/blob/master/Routing/AnnotatedRouteControllerLoader.php. You may wish to modify it to support additional annotations.
I hope this helps.
I can easily render a template with variables from a file with some code like:
$renderer = new PhpRenderer();
$vm = new ViewModel();
$resolver = new TemplateMapResolver();
$resolver->setMap($this->templateMap);
$renderer->setResolver($resolver);
// Set the template to use and pass in variables as you normally would a view
$vm->setTemplate($template);
if ($vars) {
$vm->setVariables($vars);
}
$content = $renderer->render($vm);
I am curious how I can provide a string to setTemplate rather than a path to a template file. This way, the content being passed in can come from various sources such as an administrator's panel or database.
In the configuration example in the documentation you can see that it is possible to define a template_map inside your view_manager config array. A template map is like an array of aliases for your template files. So inside your module.config.php:
'view_manager' => array(
//...
'template_map' => array(
'name_from_admin_panel' => __DIR__ . '/../view/layout/view.phtml',
'name_from_database' => __DIR__ . '/../view/layout/view.phtml',
)
//...
)
Now you can use these names from your template map to set the template in your ViewModel as normally:
$template = 'name_from_admin_panel';
$viewModel->setTemplate($template);
I am working with the TWIG framework for php, and would like to know how i would be able to include these php files inside my php code like i normally do.
<?php
session_start();
include("includes/db.php");
include("functions/searchfunctions.php");
include("functions/userSearchSession.php");
?>
The db file establishes the connection through mysqli to the database.
In your comments you mentioned you are using the Slim framework, which has an extension to support Twig templates.
Using the extension however, requires some additional setup though, you must install the extention, called Slim Views, and also the Twig core from within composer. Slim Views does not list Twig as a dependancy.
To get this working:
Use composer to get add both Slim Views And Twig
$ php composer require slim/views
$ php composer require twig/twig:~1.0
Configure your Slim Framework $app to use the new tempting engine.
$view = $app->view();
$view->parserOptions = array(
'debug' => true,
'cache' => dirname(__FILE__) . '/cache'
);
$view->parserExtensions = array(
new \Slim\Views\TwigExtension(),
);
At this point, Slim Framework is now using Twig when rendering pages. You can now do all of your includes and pass the variables to Twig:
<?php
// ./Slim_app.php
require 'vendor/autoload.php';
/*
* foo.php contains the following:
* <?php
* $foo = bar;
*
*/
require 'foo.php';
$app = new \Slim\Slim(array(
'view' => new \Slim\Views\Twig()
));
$view = $app->view();
$view->parserOptions = array(
'debug' => true,
'cache' => dirname(__FILE__) . '/cache'
);
$view->parserExtensions = array(
new \Slim\Views\TwigExtension(),
);
$app->get('/hello', function () use ($app, $foo) {
//twig_template.html.twig exists in the templates directory.
//(./templates/twig_template.html.twig)
$app->render('twig_template.html.twig', array('foo' => $foo));
});
$app->run();
?>
{# ./templates/twig_template.html.twig #}
{{ foo }}
Navigating to Slim_app.php/hello now displays the following:
More info on using Twig.