I'm new to web development with Symphony2 (though definitely not new to web development), and I'm just about to begin a medium sized project, which will be sliced in bundles, as each installation of the app may have a different setup of available functionality.
I would like to generate my navigation dynamically from the available bundles, e.g. if the bundle "foo" is active, a menu entry with a route to the foo main controller action should appear.
Normally, my take on this would be to create a singleton somewhere, which I then would fill during the load() function of a bundle, and during rendering, I would output the singleton.
But symfony2 offers a lot flexibility at this part, so I'm currently evaluating if there may be a better way.
Could services be a way to go here? Or events? Or something with dependency injection, so the bundles get an instance of a NavigationConfigurationElement at construction time?
Any input or thoughts on this, or maybe some links to examples how to do this, would be greatly appreciated.
Best regards,
Jens
i thing the best way to do it, is to use dependency injections tags. you will have to create a dependency injection extension and offer a "tag" that can be used by the various bundles to register their menu entries.
i will not describe you the whole process here because there is plenty of resources about that in the internet.
but to give you a quick outline of what to do
implement a service holding the menu entries (the singleton you where talking about)
process the tag by implementing a compiler pass, this compiler pass will look for all services tagged with the navigation class and register them with the menu service
create a twig function that will use the service to retrieve the menu and render it
write bundles that use the tag and provide menu items
here are some resources that might help you:
http://symfony.com/doc/current/components/dependency_injection/tags.html
http://miguel.ibero.me/es/post/2012-04-28/adding-tags-to-symfony.html
i'm currently implementing a solr bundle for symfony that uses DI tags as well. i have a class called IndexManager that manages various solr indexes from different bundles. i use the DI tag so other bundles can register content/entities they want to be indexed in solr. the principle is the same as with the menu items.
see here: https://github.com/roomthirteen/Room13SolrBundle
the important files are:
adding the compiler pass: https://github.com/roomthirteen/Room13SolrBundle/blob/master/Room13SolrBundle.php
the compiler pass itself: https://github.com/roomthirteen/Room13SolrBundle/blob/master/DependencyInjection/Compiler/SolrCompilerPass.php
hope that helps. any more questins? don't hesitate to ask.
Related
I look for a tutorial, help or an example that tells me what I have to do to write a grid element like 2-colums in basic typo3 (v9) with fluid but no other extension like gridelements, DCE, Templa Voila, etc. I want the same gridelements can do but I dont want to be depended to this extention and move it in my own site extention.
I tried the same with normal content elements (CE) like here:
https://docs.typo3.org/c/typo3/cms-fluid-styled-content/9.5/en-us/AddingYourOwnContentElements/Index.html
But how can I nest a CE in a CE? And how can I do this by drag&drop in the backend?
You can't. The page module doesn't support nesting
You can't nest CEs in a CE. On database level this would mean that you have to make a tt_content record a subrecord of a parent tt_content record. You run into several problems, basically the multilanguage support will be broken and the shortcut element does not function as you will expect it to. That is why the extensions "gridelements" and "mask" exist.
I integrated the gridelements configuration into my sitepackage. So I do not need to bother anymore with it.
Just for your info:
There is now an initiative that works on integrating this functionality into the core (Structured Content Initiative, https://typo3.org/article/a-structured-content-initiative/). Stay tuned to it.
There is nothing special about providing Gridelements via external files, since it's based on TSconfig, TypoScript and Fluid. That's why there is not that much about it in the documentation, since it's the same thing you would do with any other kind of sitepackage. The TSconfig and TypoScript parameters are already explained there, while the Fluid would be up to you anyway.
To have a kind of kickstarter just take any extensions providing Gridelements layouts as an example. A very popular one would be bootstrap_grids, which can be found in the TER or here: https://github.com/laxap/bootstrap_grids
You don't necessarily need the flexform controller of that extension, but the Configuration and Resources folders, show you how to configure stuff and you can see how that is included via ext_localconf.php
There are even comments i.e. in the TSconfig files to explain what is possible there and how to handle i.e. mixed environments with record and file based setups. Although it would be recommended to go for files.
You would at least have to add the necessary backend rendering methods to a draw item hook, that will modify the preview of the container element.
So basically you would have to rewrite everything that DCE, Flux, Gridelements or other similar extensions already do.
Which brings us to the question, why you want to avoid those extensions, since especially those three are well known, widely spread, well supported and available for currently supported TYPO3 versions.
I often have the situation where the wording of specific strings from various modules or core features needs to be changed for specific tenants & themes in Orchard CMS.
For example, I may have a client that prefers to have the shopping cart checkout button say "Checkout Now" rather than "Go to checkout" which is a string contained within a view in a shopping module.
I can simply override the razor view in my theme and change the string, however views often are quite complex, and it doesn't feel right overriding a view just to change one string.
Another approach I have tried is to define a po translation file within my theme to override the string from the module. This works because the strings in the module are defined using the T() syntax. However, I've noticed that as soon as I define an override for a string within my theme, this override effects all tenants, instead of just the one tenant that has this theme enabled. I'm inclined to think that translations within modules/themes should be ignored from tenants where they are not enabled.
So I'm left wondering what the best approach for this scenario is?
The localisation/po file approach would be ok if tenants ignored po files from themes that aren't enabled, but then again, it would be really nice if there was a module or feature in core that allowed you to specify string overrides via the admin interface. I guess it's more of a "rewording" task than a "translation" task.
The preferred way of doing this is through template overrides. If you don't want to do that, you can actually break shapes down, and delegate the rendering to smaller templates that are easier to override. This is done by simply refactoring the part of a template that you want to be able to override individually into a separate template. This post explains how to do that: http://weblogs.asp.net/bleroy/creating-shapes-on-the-fly
If you're not willing to do that, you can use this module to get strings from the database instead of po files: http://gallery.orchardproject.net/List/Modules/Orchard.Module.Q42.DbTranslations It should be possible to modify it to fit your sceanrio.
We are working on plugin for ReSharper and we want to make our plugin extensible. Seems, we should use ShellComponent attribute to do it but we can not find any examples. Could anybody enplane how to define custom extension point and how to manage extension. Example of code of extension point and extension implementation would be very helpful.
Thanks.
If you're looking to write a plugin that can extend ReSharper, you need to tell ReSharper about the classes in your plugin, by marking them with the [ShellComponent] or [SoutionComponent] attributes. These attributes have different lifetimes - a shell component lasts the lifetime of ReSharper itself, and a solution component is created when a solution is opened and disposed when the solution is closed.
To make ReSharper do something useful with your components, they typically have to implement an interface, such as ICodeCompletionItemsProvider, and sometimes have to use a different attribute, such as [CodeCleanupModule] (which itself derives from ShellComponentAttribute). There are many extension points in ReSharper, and the one that's appropriate for you depends on what you're trying to do - refactoring, unit test provider, code cleanup, code completion items, etc. The devguide provides a good introduction to the more common extension points.
But if you want to make your own plugin extensible, then your component needs to work with a kind of provider pattern, by deferring work to multiple provider instances. For example, code cleanup works by deferring to multiple code cleanup modules, each responsible for cleaning up a different aspect of your code (whitespace, ordering, etc). To do this, your component should take in a collection of providers in the constructor. ReSharper's component model will automatically create a collection of these types and pass them to. More specifically, you should have a constructor that takes an IEnumerable<T> or IViewable<T>, where T is the interface of the provider you're going to define and call. The IEnumerable<T> will give you a simple collection of providers, but IViewable<T> represents an observable collection, and allows you to subscribe to notifications of new providers being made available from the component model.
For our Xpages application stack we have to create cca. 100 controls that will cover our new UI parts/helpers and some additional services. These controls are meant to be very general and have to be used by many Xpages applications. Now question is how to share these controls among applications(databases). Controls need some managed beans to work, also some CSS, JS and images. To copy the whole stuff into each application and maintain it somehow is not the way (even design inheritance doesnt help here). What's more ... mixing these 100 controls among application specific controls is real hell as controls doesn't support any namespaces or some packages grouping (like java in Package Explorer), so at the end we have very long list of controls in DDE which is nightmare to navigate and work with.
We tried to use Extension Library approach and followed this tutorial
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Master_Table_of_Contents_for_XPages_Extensibility_APIs_Developer_Guide
... but honestly I tried 3 times on my computer from scratch and even example project from tutorial didn't work properly and still caused some errors in update site project. My colleague also tried this on his computer with no luck. And entire process as described in the article above is set of many java classes, XML and configuration files even for small control (eclipse plugin project -> feature project -> updated site project and then you have to install this update site test it and when bug occurs you have to run another cycle ...). Comparing to e.g. this http://tapestry.apache.org/component-classes.html its extremely heavy weight approach in Xpages.
So my question is, is there any other approach that can help us in this area to share controls among applications? Or is there any update expected in this area for upcoming Notes release e.g. R9.1 ?
the most efficient way to share controls is an extension library. It does come with a learning curve. You could use Nathan's XSP Starter Kit to ease your pain. Alternatively you can use the import/export plug-in from OpenNTF to move controls (and their supporting files) around.
In any case: XPages custom controls do support name spaces and grouping -> just have a look at the property panel of a control. You can define:
the namespace (defaults to xc, but you are free to design your own)
the group it should appear in
icons
how it looks at design time (to hide the inner workings)
So step 1 is to group and clean and then think about the distribution. Extlib definitely would be best.
There is good ol' method for sharing design elements in NSF: templates. You can make your database a template, and then inherit just specific design elements by copy/pasting them at designer level. In design element's properties view, Design tab, look for "Inherit from the design template" property. It contains template name from which you copied the element. Watch out for the property "Prohibit design refresh or replace to modify", it should be off.
This has some consequences when deploying the application to production, though, so please, read the documentation/help about template inheritance. Especially combination with XPages/custom controls requires the template to be built and signed.
We use it to share custom controls like application layout and picklists with no problems.
I want to add a new section in control panel of liferay and within that section I want to have my custom-portlet. I did it using ext. However I want to do it with hook . Is it possible ?
I don't think it would be that easy with a hook, because of the following reasons:
You can't modify in a Hook - the class com.liferay.portal.util.PortletCategoryKeys which contains the keys for displaying the different sections. The different sections are hard-coded in this class in a String array ALL.
You can't modify the logic of PortalImpl#isControlPanelPortlet() which uses the PortletCategoryKeys#ALL to determine if the request in question is for a control panel portlet.
Then you also have another method which you can't modify with a Hook and is used extensively PortalImpl#getControlPanelCategory()
Doing it with a hook:
I have not tried this but I think if you need to do it with a hook you would have to change all those JSPs which make use of PortletCategoryKeys#ALL and the methods of PortalImpl as stated above, and provide your custom implementation for all these methods in the JSP.
I would really like to know how you implemented it with an EXT may be just the steps or the methods you have overridden. So that I can try to convert those in terms of a hook.
This is as far as my understanding goes. Hope this helps.
With the advent of Marketplace, ControlPanel has a new category named "Marketplace" and that section is introduced in a plugin. However, I never checked if 6.1 GA2 introduced a new section that this plugin just fills. Check the marketplace plugin if you can find a trace of this section implemented there.
On the other hand, nobody has yet named any section that definitely required a new section (though some have asked me how to solve the same problem). For this reason, you might want to re-think the requirement and choose one of the existing sections. If you don't, at least I'd be interested in the name and purpose of the new section - I might find a first one actually justifying this kind of implementation...