Liferay 7.4自定义Fragment中获取导航菜单项的替代方案
在Liferay 7.4自定义Fragment中通过内置服务获取导航菜单项
核心方案:使用Liferay.Service调用内置服务
Liferay提供的Liferay.Service前端API可直接调用后端OSGi服务,自动处理会话认证、CSRF防护等问题,无需手动配置基础认证,比普通Fetch更适配Liferay生态。
步骤1:获取当前站点ID
通过Liferay.ThemeDisplay获取当前站点的groupId,这是调用导航服务的必要参数:
const groupId = Liferay.ThemeDisplay.getGroupId();
步骤2:获取目标导航菜单实例
调用服务根据菜单名称获取指定导航菜单:
Liferay.Service( '/site-navigation-menu/get-site-navigation-menu-by-group-id-and-name', { groupId: groupId, name: 'Main Menu' // 替换为你实际使用的导航菜单名称 }, function(navigationMenu) { if (navigationMenu) { getMenuItems(navigationMenu.siteNavigationMenuId); } } );
步骤3:获取菜单下的所有菜单项
拿到导航菜单的siteNavigationMenuId后,调用服务获取已发布的菜单项:
function getMenuItems(menuId) { Liferay.Service( '/site-navigation-menu-item/get-site-navigation-menu-items', { siteNavigationMenuId: menuId, status: 0 // 0代表已发布状态,1为草稿 }, function(menuItems) { renderMenuItems(menuItems); } ); }
步骤4:渲染菜单项为HTML列表
编写渲染函数,将返回的菜单项数据转为HTML列表,支持递归处理子菜单:
function renderMenuItems(menuItems) { const menuContainer = document.getElementById('nav-container'); // 替换为你的Fragment容器ID const menuList = document.createElement('ul'); menuItems.forEach(item => { const listItem = document.createElement('li'); const link = document.createElement('a'); link.href = item.url; link.textContent = item.name; if (item.target === '_blank') { link.setAttribute('target', '_blank'); } listItem.appendChild(link); menuList.appendChild(listItem); // 递归处理子菜单 if (item.hasChildren) { getChildMenuItems(item.siteNavigationMenuItemId, listItem); } }); menuContainer.appendChild(menuList); } // 获取并渲染子菜单 function getChildMenuItems(parentItemId, parentElement) { Liferay.Service( '/site-navigation-menu-item/get-site-navigation-menu-items', { parentSiteNavigationMenuItemId: parentItemId, status: 0 }, function(childItems) { const subList = document.createElement('ul'); childItems.forEach(child => { const subListItem = document.createElement('li'); const subLink = document.createElement('a'); subLink.href = child.url; subLink.textContent = child.name; subListItem.appendChild(subLink); subList.appendChild(subListItem); if (child.hasChildren) { getChildMenuItems(child.siteNavigationMenuItemId, subListItem); } }); parentElement.appendChild(subList); } ); }
关键注意事项
- 权限控制:
Liferay.Service会继承当前用户的权限,用户只能看到自己有权限访问的导航菜单项。 - 菜单名称匹配:确保
name参数与Liferay后台创建的导航菜单名称完全一致;也可调用/site-navigation-menu/get-site-navigation-menus获取当前站点所有菜单,再动态选择。 - 性能优化:若导航层级较深,递归调用会产生多次请求,可考虑在后端自定义服务一次性返回所有层级数据。
内容的提问来源于stack exchange,提问作者Saif
相关产品推荐
相关产品推荐

