Orchard
Orchard copied to clipboard
Make a navigation menu work with LocalizationPart
I have attached LocalizationPart to MenuItem and I can create localized text from the admin panel. However, when I switch to a new default locale, a menu does not show in frontend.
This is because a clone menu item for a new locale does not have a parent menu so it is not included when we query with "DefaultMenuProvider.GetMenu".
I think we can make localized navigation work by using "LocalizationService.GetLocalizedContentItem". However, since navigation is in a core part, we can't use LocalizationPart and LocalizationService (circular reference).
Should we move the navigation to a separated module and then we can reference "Orchard. Localization"?
Example code in DefaultMenuProvider.GetMenu
var currentCulture = workContextAccessor.GetContext().CurrentCulture;
var localizedItem = localizationSevice.GetLocalizedContentItem(menuPart.ContentItem, currentCulture, VersionOptions.Published);
var part = localizedItem.As<MenuPart>() ?? menuPart; // Use master menu if we don't have localized menu
// fetch the culture of the content menu item, if any
var localized = part.As<ILocalizableAspect>();
var culture = localized?.Culture;
Or just a simple fix by moving ILocalizationService to Orchard.Core
However, this code is not efficient and not cache. We can continue work after get it work first.
Thanks.
The appropriate way is to create a specific menu for each culture and then display the proper menu based on the current culture the user has. So basically load a different menu per culture. If you are trying to make it work with a LocalizationPart then it requires development which is not necessary at the moment. To answer about moving the ILocalizationService I'd need to investigate further.
@Skrypt, could you please clarify for "Create a specific menu for each culture and then display the proper menu based on the current culture the user has"
Does this mean we will have duplicated menu list on navigation page? For example On admin navigation page
- Home (Custom Link)
- Home in language A (Custom Link)
- Home in language B (Custom Link)
- About us (Content Menu Item)
- Contact us (Custom Link)
If I understand it correctly, it will create a many menu items on the main admin/navigation page. I would like to keep the main page clean, then edit each menu and alternative language.
Here is my work around right now
Override a shape in theme MenuItemLink.cshtml
<a href="@Model.Href">@T(Model.Text.Text)</a>
MenuItemLink-ContentMenuItem.cshtml
@using Orchard.ContentManagement
@{
ContentItem contentItem = Model.Content.ContentItem.ContentMenuItemPart.Content;
}
@if (contentItem != null) {
<a href="@Model.Href">@T(Model.Text.Text)</a>
}
and use *.po file to store localization text.
However, I think it right approach should use a localization part.
Thanks for prompt reply. You made my day.
Well I can say that in Orchard Core, right now, the advertised way to do this is to use 2 different menus. I know that in Orchard there use to be some kind of contrib modules to do this but I don't remember exactly. However, I think you are right to think that this should work with a LocalizationPart. Maybe someone else could help you more on that one. We switched focus on Orchard Core now. Maybe this issue would be more appropriate to be moved to OC.
We managed this kind of situation for every web site and what we do in a such situation is:
- we add the localizationpart to the MenuWidget;
- we create a menu for each language;
- we add the MenuWidgets - one for language - at the right layer (i.e. "Default") : the layer itself choose the right menuwidget according to the current language;
I hope this could help you @aaronamm, feel free to ask if you want to see a live website using this technique.
@Skrypt @HermesSbicego-Laser Thank you so much for your suggestion. @Skrypt BTW, any chance that Orchard Core will support ORM the same as Orchard version 1. I know go to document based database is better performance but using relational database is more multiple and more flexible in many scenarios. I still prefer to use relational database for small/medium project and use help of SQL optimization and cache. Thanks.
I think we will stay with YesSQL but we will try to fill the gap missing in between using full relational database and document database. The only thing remaining is allowing to filter on fields from YesSQL which is something @sebastienros was working on last week. As far as I can tell you can also use YesSQL with it's IndexingProviders if you require to do more optimized Queries right now and it is fully relational. Also nothing prevents you from using NHibernate or EF in one of your custom modules ... but I would suggest strongly that you learn YesSQL first 😉
@Skrypt Thank you so much for your comment. You make me what to learn YesSQL and start using OrchardCore. Here is my introduction document for Orchard 1. https://docs.google.com/document/d/12IAqF6QOcN3rPKNJn5FHZTH28_NynKkTi4kJWQlBlQQ/edit
In addition, I have a comparison between OrchardCore and Orchard 1 and why I still use Orchard 1. http://bit.ly/orchard-cms-1-vs-2
However, from your suggestion, I will start using OrchardCore and try to contribute to the community.
Thank you so much.
Some informations are not complete/accurate in the second document. There is migration in OC. 1.10.2 (RC) is not RC. 1.0.0-beta2 is 1.0.0-RC2. Reporting can be done in OC too if you are using SQL Server with IndexingProviders and SQL Server JSON functions. See https://docs.microsoft.com/en-us/sql/t-sql/functions/json-functions-transact-sql?view=sql-server-ver15 Same goes with other db's but they have slight implementations differences.