[ 
https://issues.apache.org/jira/browse/OFBIZ-10601?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16661940#comment-16661940
 ] 

Dennis Balkir commented on OFBIZ-10601:
---------------------------------------

Hi Julien,

we have implemented it this way:
 # We have made a new xml-file calles {{menus.xml}} in which we include all 
menus, that we want to load.
 It looks like this:
{code:xml}
<menus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
 xmlns="http://ofbiz.apache.org/Widget-Menu"; 
xsi:schemaLocation="Component://bootstrap-basic/menu-include.xsd">    <!-- 
define resource loaders; most common is to use the location resource loader -->
 <include-menu title="accounting" name="AccountingAppBar" 
location="component://accounting/widget/AccountingMenus.xml" icon="fa 
fa-table"></include-menu>
 <include-menu title="ar" name="ArAppBar" 
location="component://accounting/widget/ar/ArMenus.xml" icon="fa 
fa-credit-card"></include-menu>
 <include-menu title="ap" name="ApAppBar" 
location="component://accounting/widget/ap/ApMenus.xml" icon="fa 
fa-calculator"></include-menu>
 <include-menu title="catalog" name="CatalogAppBar" 
location="component://product/widget/catalog/CatalogMenus.xml" icon="fa 
fa-book"></include-menu>
 <include-menu title="content" name="ContentAppBar" 
location="component://content/widget/content/ContentMenus.xml" icon="fa 
fa-clipboard"></include-menu>
 <include-menu title="contentmgr" name="EcsCmsAppBar" 
location="component://ecs-cms/widget/contentmgr/menus/CmsMenus.xml" icon="fa 
fa-copy"></include-menu>
 <include-menu title="facility" name="FacilityAppBar" 
location="component://product/widget/facility/FacilityMenus.xml" icon="fa 
fa-building-o"></include-menu>
 <include-menu title="humanres" name="HumanResAppBar" 
location="component://humanres/widget/HumanresMenus.xml" icon="fa 
fa-users"></include-menu>
 <include-menu title="ecs-integration" name="MainAppBar" 
location="component://ecs-integration/widget/EcsIntegrationMenus.xml" icon="fa 
fa-copy"></include-menu>
 <include-menu title="manufacturing" name="ManufacturingAppBar" 
location="component://manufacturing/widget/manufacturing/ManufacturingMenus.xml"
 icon="fa fa-industry"></include-menu>
 <include-menu title="marketing" name="MarketingAppBar" 
location="component://marketing/widget/MarketingMenus.xml" icon="fa 
fa-line-chart"></include-menu>
 <include-menu title="ordermgr" name="OrderAppBar" 
location="component://order/widget/ordermgr/OrderMenus.xml" icon="fa 
fa-shopping-cart"></include-menu>
 <include-menu title="partymgr" name="PartyAppBar" 
location="component://party/widget/partymgr/PartyMenus.xml" icon="fa 
fa-child"></include-menu>
 <include-menu title="sfa" name="SfaAppBar" 
location="component://marketing/widget/sfa/SfaMenus.xml" icon="fa 
fa-truck"></include-menu>
 <include-menu title="workeffort" name="WorkEffortAppBar" 
location="component://workeffort/widget/WorkEffortMenus.xml" icon="fa 
fa-list-ol"></include-menu>
 <include-menu title="webtools" name="WebtoolsAppBar" 
location="component://webtools/widget/Menus.xml" icon="fa 
fa-home"></include-menu>
 <include-menu title="solr" name="" location="" icon="fa 
fa-search"></include-menu>
 </menus>
{code}

 # We wrote a new class, which then reads the xml file and puts all menus in a 
map:
{code:java}
/**
     * Creates a Map of all Application Menus
     *
     * @param resourceName
     *            Componentlocation of the menus.xml
     * @return modelMenusMap which contains all Menus
     * @throws IOException
     * @throws SAXException
     * @throws ParserConfigurationException
     */
    public static Map<String, ModelMenu> getMenusMapFromLocation(String 
resourceName) throws IOException, SAXException,
            ParserConfigurationException {
        Map<String, ModelMenu> modelMenusMap = new HashMap<>();
        URL menuFileUrl = FlexibleLocation.resolveLocation(resourceName);
        Document menusFileDoc = UtilXml.readXmlDocument(menuFileUrl, true, 
true);
        modelMenusMap = readAppMenusDocument(menusFileDoc);
        menuLocationCache.putIfAbsent(resourceName, modelMenusMap);
        modelMenusMap = menuLocationCache.get(resourceName);

        if (UtilValidate.isEmpty(modelMenusMap)) {
            throw new IllegalArgumentException("Could not find menu file in 
location [" + resourceName + "]");
        }

        if (modelMenusMap.values() == null) {
            throw new IllegalArgumentException("no Values in modelMenusMap");
        }
        return modelMenusMap;
    }

    /**
     * Reads Xml File and creates Map of Menus, based on given Doc
     * 
     * @param menusFileDoc
     *            menus File, where Location,Name and Application are defined
     * @return modelMenusMap which contains Menus
     * @throws IOException
     * @throws SAXException
     * @throws ParserConfigurationException
     */
    public static Map<String, ModelMenu> readAppMenusDocument(Document 
menusFileDoc) throws IOException, SAXException,
            ParserConfigurationException {
        Map<String, ModelMenu> modelMenusMap = new HashMap<>();
        if (menusFileDoc != null) {
            // read document and construct ModelMenu for each menu element
            Element rootElement = menusFileDoc.getDocumentElement();
            if (!"menus".equalsIgnoreCase(rootElement.getTagName())) {
                rootElement = UtilXml.firstChildElement(rootElement, "menus");
            }
            for (Element menuElement : UtilXml.childElementList(rootElement, 
"include-menu")) {
                String name = menuElement.getAttribute("name");
                String location = menuElement.getAttribute("location");
                String application = menuElement.getAttribute("title");
                if (!location.equals("")) {
                    modelMenusMap.put(application, 
getMenuFromLocation(location, name));
                } else {
                    modelMenusMap.put(application, null);
                }
            }
        }
        return modelMenusMap;
    }
{code}

 # In the template {{TopAppBar.ftl}} we assigned a variable of the type map, 
which uses this helper method to get all the menus:
{code:java}
<#assign MenuAppbar = 
Static[classPath].getMenusMapFromLocation("component://theme/menus.xml")>
{code}

 # We iterate through the child menu of the application like this:
{code:java}
<#assign activeApp = thisApp?remove_beginning("/")>
<li><a><i class="${iconMap[activeApp]!}"></i> <#if uiLabelMap?exists> 
${uiLabelMap[display.title]}<#else> ${display.title}</#if>. <span class="fa 
fa-chevron-down"></span></a>
    <ul class="nav child_menu">
        <#-- Sub Menus -->
        <#assign  activeAppBar = MenuAppbar[activeApp]!>
        <#if activeAppBar?has_content>
            <#assign appbar = activeAppBar.getMenuItemList()>
            <#list appbar as app>
                <#assign ui = app.title>
                <#if currApp == activeApp>
                    <#assign urlTarget = thisApp +"/control/" 
+app.link.getTargetExdr()>
                <#else>
                    <#assign urlTarget = thisApp +"/control/" 
+app.link.getTargetExdr() + externalKeyParam!>
                </#if>
                <li><a href=<@urlTarget?interpret/>><@ui?interpret/></a>
            </#list>
        <#else>
            <#assign urlTarget = thisApp +"/control/main">
            <li><a href=${urlTarget}>${uiLabelMap.CommonMain}</a>
        </#if>
    </ul>
</li>
{code}
For Facility it will produce something like this as a child menu of the 
application:
{code}
<ul class="nav child_menu" style="display: block;">
    <li class="current-page"><a href="/facility/control/main">Main</a></li>
    <li><a href="/facility/control/FindFacility">Facilities</a></li>
    <li><a href="/facility/control/FindFacilityGroup">Facility Groups</a></li>
    <li><a href="/facility/control/FindInventoryItemLabels">Inventory Item 
Labels</a></li>
    <li><a href="/facility/control/FindShipmentGatewayConfig">Shipment Gateway 
Config</a></li>
    <li><a href="/facility/control/FindShipment">Shipments</a></li>
    <li><a href="/facility/control/InventoryReports">Reports</a></li>
</ul>
{code}

I hope I didn't miss anything.

If you have more questions or something doesn't make sense, please feel free to 
ask.

Thanks

> Add a framework method to get main webapp menu with the webapp name
> -------------------------------------------------------------------
>
>                 Key: OFBIZ-10601
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-10601
>             Project: OFBiz
>          Issue Type: Improvement
>          Components: framework
>            Reporter: Julien NICOLAS
>            Assignee: Julien NICOLAS
>            Priority: Minor
>         Attachments: HomeMenu.png, webAppMainMenu.png
>
>
> To improve theme management and provide better tools for new themes, I would 
> like to have a method that return the main menu of a webApp with the webApp 
> name.
> The purpose is to have new theme with smarter UI like example in attached 
> screenshot.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to