Symfony2, how create a widget like a standalone class - symfony

Let's start with basic thing, simple example is Yii. It has such thing as widgets. Standalone, configurable and callable from any place we want classes. And I'm wondering can symfony2 has the same? What it will be? Controller in bundle? Action simple (method)? Widget (twig) with parameters?
In Yii we create class (of widget), standalone, describe it and use (by calling in template). How will it look like in symfony2?
Simple example 'i want create menu navigation using widget, where it will construct html by user roles'.

Symfony doesn't provide such a feature however you can make them yourself. They are few ways of doing it.
I'll just admit that we are talking about widgets that could do backend work (i.e. get data from DB, call an API, etc.).
1 - The scalable way
The use of the render tag in Twig which allows you to call a controller action from a template. It's scalable because you could use esi tags with Varnish (you can also implement your own caching profiles).
As a bonus, the profiler will show details about the specific render calls in the timeline (it will look like a subset of the entire request).
2 - Include a template
The included template gathers the data through a Twig function call. By experience, it's a bit faster than the first solution however it's not easily scalable.
3 - Render through a custom TwigExtension
The twig function will get the data and call the renderView method of the template service. If you are planning on doing this, you probably want to use the first method.
Conclusion
If you have a big website with modules/widgets that gets a lot of traffic (or "hit"): use the first solution.
If you have a small website with no support for caching: use the second solution. You'd use this solution if the module/widget is super light.
If you are thinking about the third solution... it's probably a good idea to use the first solution.
Personally, I'll always try to use the first solution and try to boost the performance one way or another. The render call in Twig has been significantly improved since the last versions of Symfony2.
Hopefully, my answer will provide you some guidelines.

Related

how to feed the ::base.html.twig with datas of database more proprely?

in my symfony application i use many controllers . They render their templates who all extend ::base.html.twig template. I feed these templates with an array of datas for display the dynamic content , thanks to my controllers. But the ::base.html.template need also to receive his array of datas for display 4 pictures in a kind of slider . These datas (url of pictures) come from datas base and are available for all pages in my website so i'am asking myself how to send just one time this array of picture? For moment in every controllers I have to repeat the same code for get the url of pictures from database .
Sorry if my question is not clear
I'd personally move the code that creates these sliders out of the controllers into a service layer, be it a proper service or simply a class you create and use dependency injection you need to access things like the EntityManager within it. Services are fine, but they have an associated overhead.
By moving the code out of the controllers, you have a method you can call from all the controllers and one copy of the code, instead of multiple copies through your controllers.
Rendering controllers within twig is certainly possible, but it seems a bit of a fix for bad design (in my opinion anyway). It's a quick win, but not exactly an efficient one.
Remember, controllers should be thin, not bloated fat with code.
I think the correct way would be to create a Twig extension that will get this data for you.

Symfony2 inject an array of services into a controller from config.yml

How I can inject an array of services from config.yml giving class names (with namespaces) to a controller? I need to run a function from each of this services in the controller. At the moment I use $this->get('service'); in the controller, but I need to make controller independent from services. Is there a way to do this?
Edit
I don't know names and how many services will be injected, though all of them implement an Interface.
Edit2
Well, probably I did not express correctly my thoughts. I have a bundle named Widgets. It has an array of widget names, display widget holders for each widget and with AJAX I get the content and display it. At the moment I have in the Widget controller hardcoded some widget deffinitions (title and id for Ajax) and some are retrieved by calling getWidgetList from some controllers from another bundle. Well I need that the list of the widgets wont be hardcoded itself in the widget bundle. I need a way to pass this list from the config.yml. Any ideas?
Injecting an array of services is, generally speaking, not the right approach (even if there was a way to do it, which I don't think there is)
The whole reason you don't want to write container-dependent code is to keep your codebase flexible, lithe, and testable. A variable array of services is, in practice, just a mini container, so if you implemented that you'd just be shrinking the scope of the problem, not eliminating it. You'd still be making your code dependent on an arbitrary bucket of services.
I strongly recommend explicitly defining each service your controllers need (as outlined by the links in the comments from Rufinus and Cerad) or look into using something like the jms/di-extra-bundle.
Update
Maybe you need to do more research on the configuration options available?
How to Create Friendly Configuration for a Bundle
The Config Component
http://symfony.com/doc/current/cookbook/bundles/configuration.html

Best practices approach to multiple views in meteor?

Every tutorial/example i can find for meteor shows a single view application. I would like to build something a little more complex. I'm unclear how to approach multiple views...preferably in a way that's somewhat scalable?
The iron-router package lets you access different views (layouts) by nice, REST-ful human-friendly clean URLs. It supports parameters in the URL, "loading" templates, waiting for subscriptions to finish loading, before and after hooks etc.
At this point you can only create Single Page applications with Meteor. Note that Single Page, doesn't mean you can't have several views - use iron-router for that.
But by design, Meteor serves a big fat unique JavaScript/HTML/CSS application down to the browser, though there's a feature request to allow incremental loading. It is then up to the application (or more precisely, the JavaScript framework), to dynamically render its views in order to display different "pages".
I was wondering the same thing and it took me way too much time getting something started. I finally got a paged app working solidly by using Backbone views and routes, so I created a simple boilerplate project to make setting up an app like this easier in the future.
Live demo here: backbone-boilerplate.meteor.com
Source code here: github.com/justinmc/meteor-backbone-boilerplate
Have you looked at madewith.meteor.com?
A bunch of apps there have multiple views using Backbone also Jonathan Kingston who created britto has started simple meteor framework called Stellar
At this stage of the game not sure if there really are best practices. But these two seem to be the current flow.
You can also make a tabbed interface for multiple views. There is a package project "Smart package for generating a tabbed interface with pushState" github project here: https://github.com/possibilities/meteor-tabs
The best solution right now is using a routing package (router is basic but works). The workflow is something like this:
declare routes; return a template name for each route
place the reactive helper provided by the package in your body tag
the reactive helper will return the template associated to that route
you create a template for each route and optionally set custom publish functions
Router will give you browser history (client side).
Note that at this time there are some limitation on the way Meteor handles html/js. They are load all at the same time. The bright side is that once the app is loaded, page transitions will be instant.

Symfony bundle composition, how do I structure my code when using multiple bundles

I'm looking for some guidance on best practice around how to structure my Symfony 2.0 application. If I have a few bundles (Cart Bundle, Product Bundle, CMS Bundle) and I wish to use aspects of all of these bundles when composing my page how should I best do this?
I can imagine two ways to do this, but am looking for guidance on which (if either) is correct.
1) Expose all of the functionality of my bundles through services, and have these services available to use directly from within twig. This way I can pass my routing request to the most appropriate bundle (so http://myclient.org/User/Account) is passed to the ClientUser bundle to handle, but the base template which has a mini shopping cart in the navigation is able to access the information it needs directly from within twig (I don't need to pass this in)
2) Create a bundle that accesses all the other bundles in order to build up the page (like VendorFrontend or VendorBackend). This would mean that ALL routing requests would be passed to this bundle and this bundle would access the required information for every part of the page before passing off to the template.
The first option feels wrong because I'm not sure if it's even possible to allow Twig to consume services directly (though the service container)?
Second option feels wrong because It's like using a second router, the routes would be being passed into a bundle, which only exists to compose the other bundles (it's a given here that this bundle is tightly coupled to the bundles that it uses). Surely this goes against the concept of a 'bundle' that the code is reuseable.
In this example I'm trying to build a very simple e-com site for demonstration purposes only. I have a base template which will have a primary navigation, mini shopping cart, 'body' and footer. I'm storing this in the /app/Resources directory. I was planning on having all other templates inherit this one and overriding the 'body' area.
Not looking to be spoonfed, just a nudge in the right direction. Thanks.
I think that it's important to get away from the idea that, in order to generate a "page", one has to corral together all the variables that the templating involved might need in order to render, and then pass these into a template. A controller should be doing only the specific thing for the request it's serving, and no more. So if there's a specific product referenced in a URL, fetch the product and pass it into the template. If there's a specific product referenced but it doesn't exist, or shouldn't be shown, you respond with a 404/ 410/ whatever is appropriate. If there's a specific collection, fetch the collection and pass it in. The routing/ controller should be decoding the request - the URL itself, the HTTP method, etc - and translating that into something specific. Anything general and not specific to a particular request doesn't belong there.
It's also important, I would say, to abstract as best you can the bundles you use from Twig templates. I am advocating more that templates "pull" what it needs into them, rather than being pushed in, but this is achieved by the definition of Twig functions within bundles that can themselves, via the DI container, hook into data that may or may not be in the current request, etc. So you make a Twig function that can take as a parameter anything that might change - if it has to do with product categories, let it take a product category object as a parameter.
Essentially the answer is more 1) than 2), but you shouldn't be accessing services directly through Twig - you should be proxying via functions that make semantic sense within the template, that themselves are defined to have services injected into them at runtime, services that you are at liberty to define differently in any new bundles you include or write.

How do I extend a contributed module in Drupal?

How can I extend an existing module without modifying it? Actually its a contributed module, so I don't want to hack it. But I want to alter and add certain features to it.
I'm new to drupal and as I read tutorials about it, I keep hearing one thing again and again - Don't hack the core... and I believe the same applies for modules too.
Avoid hacking or forking the module if at all possible. Hacking the module gives you a lesser variety of the "hacking core" pain, and forking the module (without a distinctly superior architecture and feature set.) just muddies the module water further- making it even more difficult for sitebuilders to make an effective decision about what to use.
The best solutions are:
Use any API provided by the module. Sometimes there are functions you can use as API calls that are not necessarily intended that way.
Create the additional functionality and submit a patch to the module issue queue, so others may benefit from your work, and so you may benefit from security audits without much sweat.
Not always, but often you can go far creating a custom module that implements hook_form_alter and adds a submit handler that leads back to your module for processing.
Found a very good post about extending a module in drupal. Essential parts:
If the module uses code for a page callback that you want to change, change the page callback with hook_menu_alter().
If the module implements a theme function you want to alter, change the function associated with hook_theme_registry_alter(). In alternative, if it is sufficient to change the variables the theme function gets, then you can implement the preprocess function for that theme function (e.g. hook_preprocess_rdf_metadata() for theme_rdf_metadata(), and change the variables that theme function will get.
If the module executes an SQL query using db_select(), and assigns a tag to the query, change the executed query with hook_query_alter().
If the module implements a hook you don't want it is executed, you can implement hook_module_implements_alter() to avoid it is executed.
If the module implements an alter hook (e.g. hook_page_alter()), and you want to change what that hook altered, implement the same alter hook, being sure it is executed after the one implemented from that module.
In the case the function you want to alter is not a hook, then:
Check that function is using hooks implemented from other module. For example, node_save() invokes hook_node_presave(); if I would want to change the "changed" property of the node, I don't hack node_save(), but I rather implement hook_node_presave() to alter it.
Check that function is referenced/used from a hook; in that case, you can do something for that hook, as I previously described.
If anything I said until now doesn't apply, then it is better to create a custom module, and use the code of the other module to create it. I would also try asking a feature request for the existing module, hoping the feature is implemented.
Hacking a third-party module is never a good idea, especially because automatic updates of the module (via the Update Manager, or Drush) would not anymore possible for that module.
What module is it? Some modules provide APIs that you can extend by writing a module of your own. There are tons of modules that "extend" Views by building off of the Views API. If the module you want to extend doesn't have a good API, you can always fork it to make a version that meets your needs. Maybe it will help someone else too.
Even if we need to use some functionality we can do it in the following manner.
We need to copy the function from the module and we can paster the function in your template.php file. Than you can make chanages on that function accordingly.
To change the form shown by the module, you can simply create a module that implements hook_form_alter() or hook_form_FORM_ID_alter(). Most of the times, when you want to modify how a module behave, you also need to change the settings form it uses (or any other form).

Resources