This might be an obvious thing to you but – even after reading through a lot of manuals and blogs – I’m still not sure what exactly should a bundle in Symfony2 represent in a webpage. And it’s hard to guess it from the simple demo applications.
For example: I have a site which is divided into two parts (one is just a 2nd level domain like
example.com and another is
dom2.example.com). Each of these two parts has some sections of it’s own – sometimes the same (like news) sometimes different.
What would the correct representation of this in symfony2? Should I have
MySite\site2bundle and do the different sections via different controllers, or
…or am I getting all wrong at this?
I am also new to Symfony and will follow the results of this question with interest, but for what it’s worth, my take on it is:
A bundle is just that: a group of files, assets, PHP classes and methods, tests, etc. The logic of the grouping can be anything you like. In some cases, it’s really obvious what the grouping is and why it’s been done — for instance, if I wrote a blog system for Symfony2 and wanted to release it, I’d make it into a bundle. That’s the sort of example used most in the documentation.
But you’d also use bundles for anything you wanted to release as one little feature. Say for instance, this bundle which creates default routes for all your controllers. It’s not a fully developed plugin/feature like a blog or forum, but it’s a bit of code that I can easily import into my project, it stays totally separate from everything else, it’s a bundle.
Finally, you’d also use bundles internally to your project, in absolutely any way which makes sense to you.
My take on your specific situation:
Quick and easy:
MySite\MyCode— gets the job done, and maybe you don’t have any logical way to break up the code you’re going to write.
If there’s some more unique features between the two sites and you want to separate them out for clarity:
If you really like everything in its place, or if you have a complex project, maybe:
MySite\MySiteMain(shared features and catch-all miscellany that doesn’t deserve its own bundle)
I definitely think you want to stick to logical groups of code — so I think your example “bundles Site1\News and Site2\News” and “MySite\Site1News and MySite\Site2News” wouldn’t be the best way to go. Site1 and Site2 are implementations, so making a separate bundle for each site’s news page would seem to be counterproductive to me; you’d want to make one news component and build it to be used in two different ways.
As for your two-domains question, you can either point both domains at the same code, and test within your code for what domain is being requested, or you can check out two copies of the same code and change the configuration files slightly (this doesn’t necessarily violate the idea of DRY because you’d still edit the code in one place, then update both copies.)
The way I understand a bundle is that it is similar to what CMS like e.g. Typo3 or Drupal call a “plugin”. So it should be ideally self-contained and written in a way that it can be used on other projects too.
E.g. in your case I’d create a “staticHtmlBundle” that contains all the static pages of your website, divided within by site.com and dom2.site.com.
Then I would create a “newsBundle” that contains all the news-articles, maybe even database-driven with a little admin-section where you can edit them and assign them to different channels (in your case that is site.com, dom2.site.com). A static page from within staticHtmlBundle would call newsBundle and display its data (like e.g. a listView of the news or a detailView and so on).
If you keep everything as abstract and reusable as possible then you could even publish the newsBunde in the Symfony 2 Bundle repository and share it with the community!
The way I perceive Symfony2 bundles is that they are provide a modular system which allows you to not only extend and override the php code, but also any resources they may or may not include.
Having said that, consider you have an API and you would like to transfer an object.
How would you do that?
Of course, you can do that manually, but wouldn’t it be nice if Symfony can do it for you?
- One bundle for the client side –
- One bundle for the server side –
- One bundle housing all the data transfer objects I would like to be able to transfer –
MyCompany/CommonBundle I would have the classes I would use for my data transfer objects along with the serialization rules I would have to provide the
JMSSerializerBundle with. They may be in the form of xml, yml or php annotations.
Once you have an object filled up with the data, you can just use
FosRestBundle would serialize it for you. Serialization would depend on the routing, so you can have the object serialized in XML for one system and in JSON for another. Key point is you have different serialization formats and versioning you can utilise at later point.
On the client side, you can use simple param converter to convert the received JSON or XML to an object right in the controller with no additional hassle. You can also type in some validation rules, so you can verify if the object is populated as you expect it to be.
In my example, the
MyCompany/CommonBundle has objects that would be used by multiple applications and would be identical. Having that as a separate bundle helps you avoid code duplication and makes long term maintenance a lot easier.
I hope I managed to explain this. Any questions?
Ask in the comments. Will update the answer accordingly.