I am experiencing an issue trying to reference a particular Twig template. I am using the render method that is part of the SF2 main controller, but I clearly not referencing/using it correctly.
This is my directory/file structure:
/src
/AyrshireMinis
/CommonBundle
/Controller
DefaultController.php
/Entity
Link.php
/Resources
/views
/Default
links.html.twig
and this is the method called by the router in DefaultContoller.php:
/**
* #Route("/links", name="ayrshireminis_links")
* #Template()
*/
public function linksAction()
{
$links = $this->getDoctrine()->getRepository('AyrshireMinisCommonBundle:Link')->findAll();
return $this->render('AyrshireMinisCommonBundle:Link:links.html.twig', array('links' => $links));
}
But this is the error I get:
Unable to find template
"AyrshireMinisCommonBundle:Link:links.html.twig".
I think it's because the template "AyrshireMinisCommonBundle:Link:links.html.twig" does not exist, try changing it to "AyrshireMinisCommonBundle:Default:links.html.twig"
I had exactly the same problem with the same directory structure. The equivalent of 'AyrshireMinisCommonBundle:Default:links.html.twig' didn't work (meaning that the directory still could not be found). It worked when I changed it to 'Default/links.html.twig'
(Using Symfony 2.3 and PHP 5.3)
Related
I'm trying to manage multiple templates in Symfony. The active Template comes from a database and I have a controller which gives the correct path entry.
My Problem is to tell symfony about this path. I have searched the Twig render method in multiple classes but changes are not successfully.
My TemplateController.php
public function loadtpl() {
$repo = $this->getDoctrine()->getRepository(Templates::class);
$found = $repo->findByActive(1);
$tpl = $found[0]->getPath();
return $tpl;
}
This gives me the template path but I find no way to tell symfony about it.
UPDATE:
What I have - 2 different layouts located in templates/layout1 and template/layout2
What I get - my TemplateController (above) returns the active layout path (layout1/)
Now I can edit my twig.yaml to say twig my template path to ../templates/layout1 so I can use render(mysite.html.twig); which is located in layout1 (and layout2) but its not what I want.
What I want - I want to extend the base template path dynamically with my layout paths so that I can use the method render (mysite.html.twig) without editing twig.yaml manually.
What I need - I need the twig or symfony class to edit the main render() method but I can't find the right File. OR: Anyone have an idea which is better to solve this problem.
The render funtion expects the following params:
/**
* Renders a view.
*
* #param string $view The view name
* #param array $parameters An array of parameters to pass to the view
* #param Response $response A response instance
*
* #return Response A Response instance
*
* #final since version 3.4
*/
So as long as you pass the correct view name: #BUNDLE_NAME:RESOURCE_NAME_FOLDER:TWIG_FILE then you should be good to go.
UPDATE:
I think I understand what you need after you provided more details. As no example was provided I will try to work with realistic scenario.
Imagine you have 2 templates, blue and red, they have structure and color differences but the content is mostly the same. I would then have 2 directories under my template folder.
/app
/Resources
/views
/blue
base_template.html.twig
/red
base_template.html.twig (they can have different names it doesn't really matter)
each one would define a base_template where you set your imports and other specifics of the template.
Now on you controller you get the base_template value from the DB as your function already does.
Then in your controller, you can use that value and pass it to your template that will extend it dynamically.
public function indexAction()
{
return $this->render('AppBundle:Home:index.html.twig',["base_template"=>loadTpl()]);
}
Finally in your twig file you would extend the template like this:
{% extends base_template %}
{% block content %}
<div class="container">
My content
</div>
{% endblock %}
Here is a link to : Twig Dynamic Inheritance
I'm trying to experiment in symfony3. I'm trying to search it to google but I found no clear answer from them. This is the default controller in symfony
class DefaultController extends Controller
{
/**
* #Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// replace this example code with whatever you need
return $this->render('default/index.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
]);
}
}
If you see the return render. It will display the default/index.html.twig from the app/Resources/views/default/index.html.twig I would like to know if this possible to put my view folder in my AppBundle folder? here is my list folder in AppBundle
AppBundle
-Controller
-Entity
-Form
-Resources
-views
-default
-index.html.twig
How can I link it to the resources under my AppBundle? If you have tutorial please give link. thanks in advance
Symfony2 started with views under the AppBundle/Resources, and Symfony3 try to encourage you to separate the frontend (html/js/css) from your Business php Bundle by placing them in app/Resources.
Anyway if you want to structure the code as you describe it (like symfony2 standard), the syntax to use is bundle:folder:subdirs/views.html.twig
AppBundle // first parameter
-Controller
-Entity
-Form
-Resources
-views
-default //second parameter
- index.html.twig
- subfolder
- _included.html.twig
- subsubfolder
- _very_included.html.twig
In this example:
index.html.twig the syntax will be AppBundle:default:index.html.twig
_included.html.twig the syntax will be AppBundle:default:subfolder/_included.html.twig
_very_included.html.twig the syntax will be AppBundle:default:subfolder/subsubfolder/_very_included.html.twig
For your concrete problem it will be AppBundle:default:index.html.twig
I'm working on a Symfony 1.4 project and when I do this:
url_for('');
I'm expecting to get the URL for the index.php controller or at least http://domain/ but I'm getting this:
/sfTCPDF
sfTCPDF is a plugin that I have in this project that in my config/ProjectConfiguration.class.php is used like:
class ProjectConfiguration extends sfProjectConfiguration {
public function setup() {
$this->enablePlugins('sfTCPDFPlugin');
}
}
When I disable the plugin I get the expected result:
$url = url_for('');
> /
Or when I use it like this (Doesn't matter if the plugin is enabled or not):
$url = url_for('/');
> /
I don't understand why the plugin is causing (or even if it's the plugin fault).
Any suggestions? I can search & replace the entire project for url_for('') and put the '/'
But I really want to understand why this is happening.
After some research:
I found out that when the url_for function is called, the procedure is the next:
lib/vendor/symfony/lib/helper/UrlHelper.php url_for()
lib/vendor/symfony/lib/helper/UrlHelper.php url_for2()
lib/vendor/symfony/lib/helper/UrlHelper.php url_for1()
lib/vendor/symfony/lib/controller/sfWebController.class.php gen_url()
lib/vendor/symfony/lib/routing/sfRoute.class.php generate()
And in the last one it gets the $this->pattern here is where the pattern is sfTCPDF/:action
which means that some routing is playing. Continuing my research i found out that the plugin has a routing.yml with:
sfTCPDF:
url: /sfTCPDF/:action
param: { module: sfTCPDF, action: test }
If I delete this routing everything works as expected.
Now the question is: when do the plugin creates a routing object with the pattern of sfTCPDF and why?
I never use the url_for with an empty string.
In my routes file I use to have:
homepage:
url: /
param: { module: home, action: index }
So if I want the route for this, I use:
url_for('#homepage');
url_for uses the route name you provide to find the proper route in the cached routes table. If you provide an empty string it will take the 0 index from the table (which you can find in the file: cache/app/env/config/config_routing.yml.php.
When the TCPDF plugin is on its' route is being added as the first one that's why you get it as the url.
The solution - don't use an empty string for url_for. If you want to get the url of the homepage always use url_for('/') or url_for('#homepage').
In my Laravel 4 application's root directory, I have a folder themes. Inside the themes folder, I have default and azure.
How can I access view from this themes/default folder in a specific route.
Route::get('{slug}', function($slug) {
// make view from themes/default here
});
My directory structure:
-app
--themes
---default
---azure
I need to load views from localhost/laravel/app/themes/default folder. Please explain this.
This is entirely possible with Laravel 4. What you're after is actually the view environment.
You can register namespace hints or just extra locations that the finder will cascade too. Take a look here
You'd add a location like so:
View::addLocation('/path/to/your/views');
It might be easier if you namespace them though, just in case you have conflicting file names as your path is appended to the array so it will only cascade so far until it finds an appropriate match. Namespaced views are loaded with the double colon syntax.
View::addNamespace('theme', '/path/to/themes/views');
return View::make('theme::view.name');
You can also give addNamespace an array of view paths instead of a single path.
Here I am not accessing my project from public folder. Instead of this I am accessing from project root itself.
I have seen a forum discussion about Using alternative path for views here. But I am little confused about this.The discussed solution was,
You'd add a location like,
View::addLocation('/path/to/your/views');
Then add namespace for theme,
View::addNamespace('theme', '/path/to/themes/views');
Then render it,
return View::make('theme::view.name');
What will be the value for /path/to/ ?
Can I use the same project in different operating system without changing the path?
Yes, we can do this using the following,
Put the following in app/start/global.php
View::addLocation(app('path').'/themes/default');
View::addNamespace('theme', app('path').'/themes/default');
Then call view like the default way,
return View::make('page');
This will render page.php or page.blade.php file from project_directory/app/themes/defualt folder.
I've developed a theme package for laravel 5 with features like:
Views & Asset seperation in theme folders
Theme inheritence: Extend any theme and create Theme hierarcies
Try it here: igaster/laravel-theme
\View::addLocation($directory); works fine but the new right way to do it is using loadViewsFrom($path, $namespace) (available on any service provider).
I am using CodeIgniter framework. I have files in my controllers folder like this:
- Controllers
--- admin.php - Admin Controller
--- /Admin - Admin Folder
----- category.php - Category Controller in Admin folder.
The Url: mysite.com/index.php/admin/category says that page not found because it is trying to call the category function of admin controller but I want it to call the index function of category controller in Admin folder.
Also I am using the admin controller for create, edit etc. functions of admin controller like mysite.com/index.php/admin/create.
I think, I should use the $route array in config file. What routing should I use?
This is the default behavior of the CI core. See function _validate_request($segments) in system/core/Router.php. This function attempts to determine the path to the controller. It goes through different conditions one by one and returns the result once a given condition is met. Besides the other, there are two conditions involved:
Is it a file? (system/core/Router.php line 271, CI 2.1.2)
// Does the requested controller exist in the root folder?
if (file_exists(APPPATH.'controllers/'.$segments[0].'.php'))
{
return $segments;
}
Is it a folder? (system/core/Router.php line 277, CI 2.1.2)
// Is the controller in a sub-folder?
if (is_dir(APPPATH.'controllers/'.$segments[0]))
{
// ...
In your case the function will return once the first of the two conditions is met, i.e. when admin.php file is found.
There are two solutions:
Rename the file or the folder and refactor the application respectively.
Change the default behavior by extending the core. Basically that would conclude in changing the sequence of conditions checking. This can be accomplished by creating MY_Router class:
class MY_Router extends CI_Router
{
// ...
}
and rewriting the original _validate_request() function with changed sequence of conditions. So first checking for directory and then for function.
I would suggest the first solution, if it does not require too much refactoring.
At the bottom of your application/config/routes.php file, add something like this:
$route['admin/create'] = 'admin/category';