What is the best practice for overriding strings in Orchard CMS? - orchardcms

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.

Related

How can I make Content Items without a CommonPart appear in the content list?

I created a custom Type that has a UserPart attached to it.
According to this issue on GitHub you can't add a CommonPart to content that also has a UserPart because it causes a StackOverflowException but I would still like items of my custom Type to show up in the content list. I already store CreatedUtc and PublishedUtc in the custom PartRecord, can I manually plug these in somewhere?
EDIT: For clarification, my specific scenario is that I am building a public facing Orchard website based on existing data that was used in a private application up to this point. I have a legacy table with user accounts that need to be mapped to Orchard Users but they also represent travel agencies that visitors should be able to browse and that Orchard admins should easily be able to edit and create through the Dashboard. I got the idea to create a TravelAgency type with a UserPart from Sipke's webshop tutorial
Content Types do not require to have a CommonPart to show in the Content List. If i remember properly its done by triggering the Creatable() in your migrations.
Also if you have a UserPart, you could Lazy loaded or just reference it via Foreign Key.
Why would you like something like that to be part of the Content List? I usually keep my business-specific Content Types tucked away in a nice section, so there are easier to visualise and use for users.
There is definitely a bug but as they comment you could extend taxonomies to accomplish your task and keep in mind sometimes changing the Orchard Codebase might fit your purposes, you only have to keep track of your changes when you upgrade next time. I have done it a couple of occasions to fit my projects.
If i remember properly, its been a while.. If you look in the core code where the Content List is created it looks for Creatable() Types. digging even more inside the code, chances are the Query in charge will join the CommonPart, hence your problem. You could easily add another query in the controller and add whatever you are after. The problem though, will be refactoring the rest of actions to accommodate your your type too. Way easier isolating your new Type. had to look at it for you, check this baby: Orchard.Core.Contents.Controllers.AdminController

Drupal how to add a search filter to admin content page

I've never used Drupal before (development or managing content). I was asked to extend the admin content page to have a filter and simply don't know enough to get moving quickly.
Can anyone tell me if adding a search by text filter in the admin content area requires code or is there a CMS feature like adding a node for this task.
If code is required, is there something like a hook for this area? Not sure where to start. I will be investigating on my own but pointers to get me oriented to Drupal would help.
By default Drupal provides search mechanism ready to use. But there are also additional module which can improve search experience. You don't need any coding to use that search. You already have search form block ready to use.
Go to Structure -> Blocks and find block called "Search form". Now all you have to do is to put that block in some region and it will appear on front-end. Of course if it's not already styled by your theme it may be needed to put some extra CSS to make it look nice. There are also some template files which you can override and put some your HTML if you need.
There's also template file for search results page (which of course will work out of box also).
You may also need to create new block region if you want to place your form at some specific place, not covered by any existing region defined by your theme (easy thing to do!).
See https://drupal.stackexchange.com/q/30633/101329, the "Admin Views" module lets you configure the search form as you like.

Symfony 2 - Generate menu entries from available bundles

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.

Can I use a Kentico macro to get a partial path?

I would like to know if it is possible to use kentico macros (not necessarily coding a custom one) to access part of the rewritten URL's Path.
Example: http://www.mysite.com/Category/Subcategory/
I would like to get the last part (Subcategory) so that I may then filter content dynamically. The reason I want to use the macro is to simply not have to have 20+ different page templates only so I can have different web part properties.
Assuming you are using Portal templates, and you don't want an 'all items in all subcategories' list on the parent:
Create an Article List web part on the parent page — parent to all the sub-categories.
Set the web part Path to /{0}/{1}/{2}/% (if your path was /Home/Parent/Subcategory for example) or something similar for your environment.
Use the default setting of Inherit for the page template for all subcategory pages.
This will not show anything on the parent page, and the sub-categories will show only the documents under themselves. Note: If you want the subcategory items to have their own views when user digs down to /{0}/{1}/{2}/item, you may need to filter by changing template inheritance, or Document Types on the web part, or something like that if you don't want the whole sub-category list to also show on the item-specific pages.
You can create a custom macro or, you can also use the string operations which are allowed within macros. Please see http://devnet.kentico.com/docs/6_0/devguide/available_macro_methods.htm#string_methods (and you can e.g. use the EndsWith or TrimStrart or something similar).
However, I think the best way would be to create a custom macro which will exactly fit. There might be some combination of macros and macro functions - but I think it is faster just to code a custom one which will cover your need 100%.
Also, you can take a look on the K# if there is something that will fit - http://devnet.kentico.com/docs/6_0/devguide/ksharp_syntax.htm

SharePoint SPContext.List in a custom application page

I have a custom SharePoint application page deployed to the _layouts folder. It's a custom "new form" for a custom content type. During my interactions with this page, I will need to add an item to my list. When the page first loads, I can use SPContext.Current.List to see the current list I'm working with. But after I fill in my form and the form posts back onto itself and IsPostBack is true, then SPContext.Current.List is null so I can't find the list that I need to add my stuff into.
Is this expected?
How should I retain some info about my context list across the postback? Should I just populate some asp:hidden control with my list's guid and then just pull it back from that on the postback? That seems safe, I guess.
FWIW, this is the MOSS 2007 Standard version.
Generally speaking I try and copy whatever approach the product group has taken when looking to add functionality of my own. In this case they add their own edit/view/add pages via the list definition itself.
I built a solution that also needed its own custom "New" form, not open source unfortunately, though if you are interested you can download it, its called "Tagged Links" (Social Bookmarking for SharePoint) and you can find some links on my blog.
To give you a few hints and tips, the following should set you off in the right direction:
Created a new list definition.
Created a new Content Type In the content type you can define your own "FormTemplates" that references a Rendering Template which determine what gets displayed in the "Middle" bit of those forms.
Copied the standard Rendering Template, but then made the changes to it that I
needed.
Wrapped it all up in a solution, and deployed.
My Rendering Template actually included an overridden "Save" Button where I did a lot of the extra work I needed to do during the save.
Anyway, it is a little too much work in my opinion but, I think, it most closely matches the standard approach taken by the product developers. Let me know if you need more detail and I will see if I can put together a step-by-step blog post, but hopefully this gets you off on the right direction.
I would be surprised if you could do something in a _Layouts file that you can't do in a forms template. You have pretty much the same technologies at your disposal.
Looking at the way SharePoint works with ListItems and Layouts pages (for example "Manage Permissions" on a list item), I can see that they pass some variables in via querystrings:
?obj={76113B3A-FABA-4389-BC85-4BB2CC5AB423},6,LISTITEM&List={76113B3A-FABA-4389-BC85-4BB2CC5AB423}
Perhaps they grab the context back each time programmatically using these values.
I'm not using a custom "new form", so this might not apply. I added an event receiver to my custom content type and then do my custom code in the ItemAdded or ItemAdding events. This code fires when the event is added to a list. You can use the event receiver properties to get to the parent List, Web, and Site.
I'd like to think my issue is "special" here, since I am using a custom form. I chose to use a custom form rather than a custom FormTemplate simply because I'm doing a lot of stuff that's not very SharePoint list-like (making ajax calls to get info from a third-party app then generating some dynamic form elements based on that ajax result, then subsequent processing of that data on postback). I thought it'd be a nightmare to try this within the usual custom rendering template mechanism.
I also don't think I can supply the custom form declarations in the list definition itself, because I have multiple content types associated with this list, and each content type has its own custom form (the other type is thankfully much simpler).
Actually, my simple way of keeping the list guid in my hidden field was a very low impact way to address this specific problem. My main concern is that I'm not sure why the SPContext just loses all its usefulness when I postback here, which makes me think I'm doing something wrong.

Resources