Base solution for your next web application
Open Closed

New Module with Navigation and Language #853


User avatar
0
princedis created

Hi. In our project, We decided to separate the core of each activity as module itself like "Inventory", "Purchase". And in each, I have defined Navigation Menus as well. Along with custom Localizatation. But the entry in the xml file is not visible in admin panned so that to edit it.

Purcahase Module

PurchaseConsts.cs

public class PurchaseConsts
{
public const string LocalizationSourceName = "Purchase";
}

PurchaseModule.cs

//SASCoreModule is the main core module
[DependsOn(typeof(SASCoreModule), typeof(InventoryModule))]
    public class PurchaseModule : AbpModule
    {

        public override void PreInitialize()
        {
            //Add/remove localization sources
            Configuration.Localization.Sources.Add(
                new DictionaryBasedLocalizationSource(
                    PurchaseConsts.LocalizationSourceName,
                    new XmlEmbeddedFileLocalizationDictionaryProvider(
                        Assembly.GetExecutingAssembly(),
                        "JPY.SAS.Core.Purchase.Localization.Purchase"
                        )
                    )
                );
        }
        public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); }
    }

PurchaseNavigationProvider.cs

public class PurchaseNavigationProvider : NavigationProvider
    {
        public override void SetNavigation(INavigationProviderContext context)
        {
            context.Manager.MainMenu
              .AddItem(
                  new MenuItemDefinition(
                      "ppyTasks",
                      new LocalizableString("ppyTasks", PurchaseConsts.LocalizationSourceName),
                      url: "/Tasks",
                      icon: "fa fa-tasks"
                      )
              );
        }
    }

SASWebModule.cs

[DependsOn(
        typeof(AbpWebMvcModule),
        typeof(SASDataModule),
        typeof(SASApplicationModule),
        typeof(SASWebApiModule),
        typeof(AbpWebSignalRModule),
        typeof(AbpHangfireModule), //AbpHangfireModule dependency can be removed if not using Hangfire
        typeof(InventoryModule),
        typeof(PurchaseModule))] 
    public class SASWebModule : AbpModule
    {
        public override void PreInitialize()
        {
            //Use database as language management
            Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();
            //Configuration.Localization.IsEnabled = false;

            //Configure navigation/menu
            Configuration.Navigation.Providers.Add<AppNavigationProvider>();
            Configuration.Navigation.Providers.Add<FrontEndNavigationProvider>();
            Configuration.Navigation.Providers.Add<MpaNavigationProvider>();
            //Configuration.Navigation.Providers.Add<InventoryNavigationProvider>();
            Configuration.Navigation.Providers.Add<PurchaseNavigationProvider>();
}

how can I achieve this? is it a good practice to have separate module?


8 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    Have you marked your XML file as embedded resource?

    For modularity; It's your design decision. But beside ABP and AspNet Zero, modularity is hard itself. For example, you have 2 modules A and B isolated from each other and independent from the main app. What if you need to use some class of A from B? Will you create an abstraction into a common module? So, it may be hard. But if you are OK with these, it has obvious advantages like re-usability and maintainability.

    Have a nice day.

  • User Avatar
    0
    trendline created

    Is there an approach define navigation menu in module A, then initialize the navigation provider in main App? I also tired but navigation menu didn't show, how to archive it?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Can you share your module's navigationProvider class ?

  • User Avatar
    0
    trendline created

    <cite>ismcagdas: </cite> Hi,

    Can you share your module's navigationProvider class ?

    I defined the Module A navigation provider in the module, if I configured it in the pre-initial method in Module A, it can't work.

    But if I configured it in the top level module, such as the web module, then it works.

    public const string MenuName = "App";
            
            public override void SetNavigation(INavigationProviderContext context)
            {
                //var menu = context.Manager.Menus[MenuName] = new MenuDefinition(MenuName, new FixedLocalizableString("PM Menu"));
                var menu = context.Manager.Menus[MenuName];
    

    Furthermore, must define the menu name same as the top level module defined, such as "App", then it could append after it, is there other approach to append the navigation module from a module and don't need to define with the same menu name?

  • User Avatar
    0
    trendline created

    <cite>hikalkan: </cite> Hi,

    Have you marked your XML file as embedded resource?

    For modularity; It's your design decision. But beside ABP and AspNet Zero, modularity is hard itself. For example, you have 2 modules A and B isolated from each other and independent from the main app. What if you need to use some class of A from B? Will you create an abstraction into a common module? So, it may be hard. But if you are OK with these, it has obvious advantages like re-usability and maintainability.

    Have a nice day.

    I also encountered this issue, and there is no way to make the XML file as embedded resource in .net core project.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    The current template renders only menu with name "App", you can check [*SideBarViewComponent.cs] and Default.cshtml under "Views/Shared/[*SideBar]/".

    In your other modules you can create different menus but in that case you need to change SideBarViewComponent to render all menus instead of menu with name App.

    In order to embed xml files in your module, you can check the project.json in *.Core project.

  • User Avatar
    0
    trendline created

    <cite>ismcagdas: </cite> Hi,

    The current template renders only menu with name "App", you can check [*SideBarViewComponent.cs] and Default.cshtml under "Views/Shared/[*SideBar]/".

    In your other modules you can create different menus but in that case you need to change SideBarViewComponent to render all menus instead of menu with name App.

    In order to embed xml files in your module, you can check the project.json in *.Core project.

    Thanks, localization issues fixed follow up your suggestion. Regarding to the navigation menu, I append the module navigation menu to the menu with name "App", is there a way that I could insert the new module menu in a specified position in the "App" name?

  • User Avatar
    0
    hikalkan created
    Support Team

    Since menu items are just a List, you can insert a new menu item in a specific position in the list. Example

    public class MyNavigationProvider1 : NavigationProvider
    {
        public override void SetNavigation(INavigationProviderContext context)
        {
            context.Manager.Menus["App"].Items.Insert(3, ...);
        }
    }
    

    Sure, you must know the exact position. Instead, you can query items for find a menu with name and insert just after it. Or another option is to use MoveMenuItemBefore() extension method like context.Manager.Menus["App"].Items.MoveMenuItemBefore(...) You can play with the API to understand it better.