[jira] [Commented] (OFBIZ-10601) Add a framework method to get main webapp menu with the webapp name

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[jira] [Commented] (OFBIZ-10601) Add a framework method to get main webapp menu with the webapp name

Nicolas Malin (Jira)

    [ 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)