Symfony2 templates/layouts - symfony

I am new to symfony2 so please forgive me if this is a stupid question.
Symfony2 is organised in bundles - so everything is a bindle right?
Based on this I have created the following bundles in order to have a simple login mechanism:
App
The main bundle will contain all global functionality
User
Will be used to represent users
So the bundles work correctly and all is fine.
Now I cant figure out the best way to add a layout/theme structure to the site.
I obviously need some global assets such as header, nav and foooter. But additionally, there needs to be some global css style sheets, jquery etc.
The most obvious place bundle is App - but how do i make all other bundles inherit the theme from this bundle. For example, the user bundle template needs to extend the App bundle etc.
The idea for bundles is that they are modular and self contained, therefore how can this be achieved

I personally use like this:
There is MainBundle (in your case, it is App) which does global services, twig extensions and layout. Global assets are included in this file.
Main layout of all the other bundles extends the layout of MainBundle. Templates inside each bundle extend to the main layout of it which extend the layout of MainBundle. For example,
- MainBundle
- views
- layout.html.twig
- UserBundle
- views
- layout.html.twig (extends to MainBundle/layout)
- show.html.twig (extends to UserBundle/layout)
- friends.html.twig (extends to UserBundle/layout)

Everything is explained in the official docs: http://symfony.com/doc/current/templating.html
The basic global view (templates) resources are placed in the following dir:
app/Resources/views/index.html.twig
If you have a specific purpose, or bundles, templates, place them in the subdirs, e.g.:
app/Resources/views/blog/index.html.twig
And if you want to keep everything in the bundle (must for reusable code), use this convention:
[VendorName/]YourBundle/Resources/views/Blog/index.html.twig
(Of course, any name, except the ".html.twig" extension for Twig, may be changed to your liking)

The strategy I prefer is to organize my application in a single bundle. If you have no intention of re-using distinct standalone features across multiple applications then this is the most appropriate way. Having a "UserBundle" in your own application namespace probably doesn't make sense. You're adding a lot of extra structure that's serving you no advantage. Consider this instead:
- MainBundle
- Controller
- UserController
- OtherController
- Resources
- views
- layout.html.twig
- User
- show.html.twig
- update.html.twig
- friends.html.twig
- Other
- some_other_view.html.twig
In this case the templates under the controller directories would extend MainBundle::layout.html.twig.

Related

Correct way to override default template in Sonata

I'm a bit confused as I've seen a few varying methods posted online.
I have a bundle created with easyextends in src/Application/Sonata/SonataMediaBundle, which extends the SonataMediaBundle in the vendors.
The default template displays
This is the gallery index template. Feel free to override it.
This file can be found in SonataMediaBundle:Gallery:index.html.twig.
so I've added src/Application/Sonata/SonataMediaBundle/Resources/views/Gallery/index.html.twig in my bundle
and this works and overrides, so why all these various other ways like How to override Sonata Media Bundle templates?
You are using the correct way. To quote from symfonys How to Override Templates from Third-Party Bundles
To override the bundle template, just copy index.html.twig template from the bundle to app/Resources/AcmeBlogBundle/views/Blog/index.html.twig (the app/Resources/AcmeBlogBundle directory won't exist, so you'll need to create it). You're now free to customize the template.
And for more detailed/ complex overriding behaviour have a look at How to Use Bundle Inheritance to Override Parts of a Bundle
I wouldn't worry to much about other solutions unless you are not able to get the results you require using this method but I cant think of one.

Location for Symfony bundle templates

The directory structure for bundles specifies that views should be stored in <your-bundle>/Resources/views. But then the best practices for template locations says that, actually, I should store them in app/Resources/views. I can see the conveniences of doing the latter, but I don't understand:
If I am organizing things into bundles, aren't I reducing the bundles' portability by "de-bundling" the views?
The examples show that index.html.twig is easier to write than AcmeDemoBundle::index.html.twig, but what if I also have FooBundle::index.html.twig? I still need a way to specify which index.html.twig I want, right?
The documentation is correct. Store reusable bundle's templates in <your-bundle>/Resources/views and your project's templates in app/Resources/views. There is no conflict.
If you decide to create a bundle make sure it can be reused (that's the main purpose of the bundle). Otherwise keep using your AppBundle. AppBundle will not have two /index.html.twig's.

Specific, dynamic embed path for Twig in Symfony2

(a) A bundle (bundle 1) holds the main parent Twig template.
(b) Another bundle (bundle 2) holds a load of controllers and those controllers each render a Twig template that's inside that bundle (bundle 2). That template also extends from the main parent one mentioned above (bundle 1). Hard coding an absolute path to the main parent template is fine.
(c) The parent template (inside bundle 1) also embeds/includes another template, which is stored in the other bundle (bundle 2).
Can I set a relative path for part (c) above so that if I created another bundle (bundle 3) it would automatically work (parent template includes templates from bundle that calls it)? It would pick up the main parent as it is an absolute path, but would it pick up part (c) above? Obviously I can't use an absolute path for the templates that the parent one is embedding/including.
If I understand properly, you are asking how to extend templates easily while having dependencies from one bundle to another.
I'd advise you to read this documentation about overriding bundle templates.
Once read this, you will notice a link that points to the [bundle inheritance documentation].
As an example, we have 3 bundles with explicit names:
- GenericSiteBundle
- GenericUserBundle
- SpecificSiteBundle
We want to create a generic structure for an app that could be used by other apps and we also want them to be different therefore we need to be able to change the layout (header, footer, columns, etc.).
Template structure would be something like GenericUserBundle:Security:login.html.twig extends GenericSiteBundle:Layout:simple.html.twig.
You wish to change the simple layout with a specific one; all you need to do is declare GenericSiteBundle as the parent of SpecificSiteBundle and create SpecificSiteBundle:Layout:simple.html.twig. Make sure only the bundle name is different otherwise it won't find the template in the child bundle.
Also, you will love this parent() twig function. It allows you to grab the content of the parent block and add it into the child block.
It's not exactly what you want to do but this proper way to handle inheritance.

symfony 2.0 bundles interworking

I want to make an application based on a main bundle leaving the possibility for other developers to make their own bundles to implement other features.
Symfony 2.0 seems a good choice for that however I cannot figure out how to let the bundles to work together while preserving the decoupling.
In the MainBundle I will create a Controller which generates a Users-List like the one below:
user1 edit remove
user2 edit remove
....
How to let third-parties bundles to add their custom buttons to this list?
For example an AvatarBundle may want to add a button to upload of the Image, a SendEmailBundle my want to add a button to send an email to the user and so on.
How to preserve the bundle independency? How can I do that?
Thanks a lot,
Massimo
As far as I know, there are only two ways of changing/adding functionality in provided bundles.
Change the code
Overriding the template/controller
In this case, the second seems far preferable.
The ways to override a template are:
Define a new template in app/Resources
Create a child bundle and override the template
If you also want the override controllers, the second way is the only way to go.
It's also my personal preference, since it's cleaner then putting specific stuff in the general app-folder, in my opinion.
Anyway, it is far better explained in the documentation of the FOSUserBundle:
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_templates.md
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_controllers.md
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_forms.md
And ofcourse, this cookbook article:
http://symfony.com/doc/current/cookbook/bundles/inheritance.html
Hope this helps,
Dieter
If you know which parts of your bundle will be extended, you can use services (in the same way the tiwg bundle is using them for adding new templating filters/tags/helpers).
Your bundle will then 'scan' the services defined in the DIC (which have a defined tag) and then call them to get informations (button definitions in your case).

What goes in app/Resources and what goes in Acme/MainBundle/Resources

I am starting a new project using Symfony2. I am adding some basic twig templates like my CSS template (with assetic to trigger sass -- nifty) and my header/footer template. My question is, should this sort of thing go into app/Resources or into Acme/MainBundle/Resources?
I am sure I can do either if I really wanted to, but I'd like to know what the correct way to do it is.
app
Resources
<A. here?>
src
Acme
MainBundle
Resources
<or B. here?>
It's really a matter of preference. I tend to keep global views in app/Resources. Does your MainBundle contain anything else besides views? If not, I think that's more reason to use app/Resources and avoid unnecessary bundle pollution.

Resources