Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>The new approach</h1> <p>After several months since I wrote this answer, my approach has changed, so I'm sharing it with the community. This answer is still pretty popular and can lead newcomers to the approach I don't think is the best one anymore. So...</p> <p>Now I have only <strong>one</strong> <em>app specific</em> bundle and I call it <code>AppBundle</code>. There were several problems with the old approach and here are some of them:</p> <ul> <li><p><strong>Creating a lot of bundles is tedious.</strong> You have to create a bundle class and a bunch of standard folders for each new bundle and then activate it and register its routes and DI and whatnot.</p></li> <li><p><strong>Unnecessary hardcore decision making process.</strong> Sometimes you just can't decide which bundle a particular thing belongs to because it's used by more than one bundle. And after you spend a half a day and finally make your hard decision on where to put it, you'll find that in a couple of days or weeks you won't be able to tell right away which bundle to look that thing in — because most of the times the decision wasn't based on pure logic and you had to choose based on a coin toss or whatever means you use to bring higher powers for help.</p> <p>I suggested using <code>CommonBundle</code> for common stuff in the past but doing that you'll have to do a lot of unnecessary refactorings moving a thing to and from <code>CommonBundle</code> based on how many or few bundles will use that thing later.</p></li> <li><p><strong>App specific bundles are interdependent anyway.</strong> When people meet the idea of bundles for the first time, one of the main thought that goes through their minds is something like “Yay! I'll have me a bunch of reusable bundles!” That idea is great and I have nothing against it; the problem is that <em>app specific</em> bundles are not that reusable anyway — there are interdependent. Forget about reuse in <em>this</em> case.</p></li> <li><p><strong>No idea where to put <a href="http://behat.org/" rel="nofollow noreferrer">Behat</a> features and step definitions.</strong> This problem is related to the previous ones: you have to repeat the same brainless motions for each bundle and then make hardcore decisions.</p> <p>When I started writing Behat features, I just couldn't decide where to put a lot of features and step definitions because they belonged to several bundles at a time. Putting them into <code>CommonBundle</code> seemed to be even worse, because that's the last bundle I would look for that stuff in. So, I ended up creating <code>FeatureBundle</code> for that.</p></li> </ul> <p>Switching to a single bundle solved all these problems.</p> <p>I've also seen some people having a separate bundle for, say, all the entities. I don't like this approach neither and actually <a href="https://stackoverflow.com/questions/9999433/should-everything-really-be-a-bundle-on-symfony-2/10001019#10001019">suggest keeping entities and other non Symfony2 specific stuff out of the bundles</a>.</p> <p>Note again that this new approach applies to <em>app specific</em> bundles. Official docs and other places are full of great advice on how to structure bundles intended to be shared with others and reused across numerous projects. <a href="https://github.com/elnur" rel="nofollow noreferrer">I write bundles of this type</a> as well. But what I've found out after months of working on Symfony2 projects is that there is a difference between the bundles intended for reuse and the app specific ones — one approach doesn't fit all.</p> <p>And, of course, when you see something reusable emerging in your app specific bundle, just extract it, put it in a separate repo and install as a vendor.</p> <p>Also I've found myself using subnamespaces much more actively as a way to partition the bundle logically — instead of creating a bunch of bundles for that and going through all those troubles. </p> <h1>The old approach</h1> <p>There are no hard and fast rules or silver bullets, but I'll share my approach of doing things — maybe it will give you an insight or two.</p> <p>First of all, I don't have two all-encompassing bundles like <code>FrontendBundle</code> and <code>BackendBundle</code>. Instead, my bundles have both frontend and backend controllers, views, etc. So, if I strip everything from my <code>UserBundle</code> except for controllers and views, its structure would look like this:</p> <pre class="lang-none prettyprint-override"><code>UserBundle ├── Controller │ ├── Admin │ │ └── UserController.php │ └── UserController.php ├── Resources │ └── views │ ├── Admin │ │ └── User │ │ ├── add.html.twig │ │ ├── delete.html.twig │ │ ├── edit.html.twig │ │ ├── form.html.twig │ │ └── index.html.twig │ └── User │ ├── edit.html.twig │ ├── sign-in.html.twig │ ├── sign-up.html.twig │ └── view.html.twig └── UserBundle.php </code></pre> <p>Second, I have <code>CommonBundle</code> which I use for stuff shared by several bundles:</p> <pre class="lang-none prettyprint-override"><code>CommonBundle ├── Resources │ ├── public │ │ ├── css │ │ │ ├── admin.css │ │ │ ├── common.css │ │ │ └── public.css │ │ └── img │ │ ├── add.png │ │ ├── delete.png │ │ ├── edit.png │ │ ├── error.png │ │ ├── return.png │ │ ├── success.png │ │ └── upload.png │ └── views │ ├── Admin │ │ └── layout.html.twig │ └── layout.html.twig └── CommonBundle.php </code></pre> <p>My <code>app/Resources/views/base.html.twig</code> is almost the same as it comes with Symfony Standard distribution:</p> <pre><code>&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset="utf-8" /&gt; &lt;title&gt;{{ block('title') | striptags | raw }}&lt;/title&gt; {% block stylesheets %}{% endblock %} &lt;/head&gt; &lt;body&gt; {% block body %}{% endblock %} {% block javascripts %}{% endblock %} &lt;/body&gt; &lt;/html&gt; </code></pre> <p>Both <code>CommonBundle/Resources/views/layout.html</code> and <code>CommonBundle/Resources/views/Admin/layout.html</code> extend <code>app/Resources/views/base.html.twig</code>. Other bundles' templates extend one of these two layouts, depending on whether they are for frontend or backend. Basically, this is how I'm using the <a href="http://symfony.com/doc/current/book/templating.html#three-level-inheritance" rel="nofollow noreferrer">Three-level Inheritance approach</a>.</p> <p>So, I'd put your date displayer into <code>CommonBundle</code>. Depending on its complexity it could be just a template, a <a href="http://twig.sensiolabs.org/doc/templates.html#macros" rel="nofollow noreferrer">macro</a> or a <a href="http://twig.sensiolabs.org/doc/advanced.html" rel="nofollow noreferrer">Twig</a> <a href="http://twig.sensiolabs.org/doc/extensions.html" rel="nofollow noreferrer">extension</a>.</p> <p>Pagination is a common problem, so I suggest you to use one of the <a href="http://symfony2bundles.org/search?q=paginat" rel="nofollow noreferrer">existing</a> <a href="http://symfony2bundles.org/search?q=pager" rel="nofollow noreferrer">bundles</a> instead of reinventing the wheel — if they suite your needs, of course.</p> <p>And yes, it's perfectly okay to have bundles without controllers or views, etc.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload