跳到主要内容
版本:5.1

菜单和菜单项

引言

Joomla 菜单和菜单项类管理网站前面对菜单和菜单项的配置和显示。菜单是一组导航链接,你可以将其用作主菜单(如位于网站顶部)或辅助菜单(如位于页脚)。每个单独的导航链接都是一个菜单项。

在整体菜单结构中,你可以使用“子菜单”。这不是 Joomla 菜单构造的方式,而是一组位于父菜单项下方的菜单项。因此,Joomla 菜单项是在有序树结构中实现的,具体使用Nested Set 模型

本文档介绍如何使用 Joomla API 访问菜单和菜单项数据,并且包括可作为功能演示安装到网站上的示例模块代码。

请注意,这些类不用于管理员后端。

基本操作

若要获取站点上所有菜单项的详细信息,请执行以下操作

use Joomla\CMS\Factory;
$app = Factory::getApplication();
$sitemenu = $app->getMenu();

如果代码在 Joomla 后端运行,则应执行以下操作

use Joomla\CMS\Factory;
$app = Factory::getApplication();
$sitemenu = $app->getMenu('site');
$sitemenu->load();

然后,$sitemenu 结构将包含有关所有站点菜单项的条目。

(不需要在前段调用 load 的原因是,在运行代码时很可能会已加载菜单项,因为它们是站点路由器功能必需的。如果您编写的站点系统插件在路由器之前被调用,那么需要自己添加 load 调用。)

Joomla API 无法使您仅获取系统上的菜单集(而不是菜单项集),因此如果您确实需要这些菜单,那么唯一的办法是直接使用 SQL 查询从 menu_types 表读取数据。但您可以从(如下所述的菜单项结构)中找到该菜单项所属的菜单,以及找到特定菜单的所有菜单项。

为了处理各个菜单项,我们使用 getItems()$sitemenu 应用筛选器,以选择我们感兴趣的特定菜单项。若要获取所有菜单项的数组,请使用空白筛选器

$menuitems = $sitemenu->getItems(array(), array());

若要获取“mainmenu”菜单中的所有菜单项,请使用以下方法

$mainmenuItems = $sitemenu->getItems('menutype', 'mainmenu');

以上内容提供了“mainmenu”菜单中的所有菜单项,包括子菜单中的菜单项。若要仅访问“mainmenu”菜单的最顶层或第一个子菜单级别的菜单项,则使用以下方法

$mainmenuItems = $sitemenu->getItems(array('menutype','level'), array('mainmenu',array("1","2")));

总之,若要筛选所需的特定菜单项,请传递一个属性数组(来自下一部分中的列表)和这些属性应具有的一个对应值数组。

不会返回未发布的菜单项。它们不包含在 $sitemenu 结构中。

如上所述,没有等效的方法可以在管理员后端获取菜单项,因为没有使用菜单和菜单项类。如果您想访问菜单详细信息,则必须从数据库中读取和解释相应记录。

属性和参数

以下为 Menuitem 类的公有属性。其中大多数在后台编辑菜单项时,"菜单:编辑项"表单的第一个标签页("详细信息")中显示。获取 Menuitem 对象后,您可以直接访问属性,如下所示。

$menuitems = $sitemenu->getItems(array(), array());
foreach ($menuitems as $menuitem)
{
echo "Itemid: {$menuitem->id}";
}
  • id – 这是菜单项的 ID。在 Joomla 代码中,通常称为 Itemid,可能是为了与例如文章的 ID 区分(因为这两个 ID 通常在不使用 SEF URL 的情况下显示在 URL 中)。
  • menutype – 这标识了菜单项所属的菜单。这是一个您分配给菜单的唯一标识符菜单类型。
  • title – 当菜单项在菜单上显示时显示的内容(在表单中称为"菜单标题")。
  • alias – 使用 SEF URL 时的 URL 片段。
  • note – 表单上显示的可选备注。
  • route – 此菜单项的 SEF URL 部分。例如,如果此菜单项的别名为"me",其父级的别名为"dad",其祖级的别名(在菜单的顶层)为"gran",则返回的路由为"gran/dad/me"。
  • link – 在表单的链接字段中显示的链接。
  • type – 通常情况下,这将是"component"且链接会指向 Joomla 中的组件功能。但是,当选择的菜单项类型是系统链接之一时,它也可能是以下之一:
    • "heading" – 菜单标题 – 子菜单项父级的标题。
    • "alias" – 菜单项别名 – 到另一个菜单项的别名。
    • "separator" – 分隔符 – 分隔菜单中项的文本字符串(例如连字符)。
    • "url" – URL – 到外部 URL 的链接。
  • level – 菜单项树中的级别。树底部的"根"条目级别为"0",菜单中顶层的菜单项级别为"1",第一级子菜单级别为"2",以此类推。
  • language – 语言代码。例如,"es-ES"。
  • browserNav – 与表单的目标窗口字段中输入的选项关联的值。通常这意味着以下内容;
    • 0 – 父级 – 链接在同一个标签页打开。
    • 1 – 带导航的新窗口 – 链接在新标签页打开。
    • 2 – 不带导航的新窗口 – 链接在新窗口打开。
  • access – 分配给此菜单项的访问级别的 ID。使用此 API 时,会检查登录用户,并且仅会返回该用户允许查看的那些菜单项。
  • home – 该项是否为网站或语言的主页("默认页面")。
  • img – 现在似乎不再使用此项。您可以指定要在菜单项中使用的图像,但这现在在表单中的链接类型标签页中指定,并存储在 params "menu_image" 字段中。
  • template_style_id – 在表单中输入的模板样式的 id
  • component_id – 与该菜单项相关组件的 id
  • parent_id – 菜单项树中的父级 id
  • component – 相关组件的名称,如“com_contact”
  • tree – 数组,获取树中到达该菜单项的菜单项 id。如果该菜单项的 ID 为 789,父级 ID 为 456,祖父母 ID 为 123,其中祖父母处于最上层菜单(即其父级为根节点),那么返回的 tree 将为数组(“123”、“456”、“789”)。
  • query – query 参数的关联数组,在表单的“链接”字段中显示。例如对于指向单个文章的菜单项,此形式为:数组(“option”=>“com_content”、“view”=>“article”、“id”=>“123”)。

菜单项的所有其他属性均存储在数据库中的 params 字段中,并使用 getParams() 方法进行访问。这些数量过多且变化多样,无法在此处全部指定。以下显示两个示例

$params = $menuitem->getParams();
$displayed = $params->get("menu_show");
$show_tags = $params->get("show_tags");

$displayed 变量将保存一个布尔值,具体取决于此菜单项是否应在菜单中显示或隐藏,这对应于表单的“链接类型”选项卡中“在菜单中显示”字段的设置。

$show_tags 变量将保存一个布尔值,用于定义是否显示与正在显示的项目关联的标签。但此字段的存在取决于菜单项指向的网页上显示的内容。如果它是文章或联系方式,则与此相关并可能会设置,但如果它是指向搜索表单或搜索结果的链接,则与此无关,并且不会设置。

其中一些参数(例如那些在菜单项编辑表单的“链接类型”选项卡中定义的参数)可能会针对一般菜单项进行定义,但存储的具体字段取决于所选的菜单项类型(即上述属性列表中的 type 属性)。若要查找这些内容,请在以下位置下的 Joomla 代码中查找:administrator/components/com_menus/forms/item_<type>.xml,将 <type> 替换为上述 type 之一。这些 xml 文件定义了“菜单:编辑项目”表单的一部分,您可以在其中找到存储在数据库中 params json 字符串中的属性名称,并通过 getParams()->get() 方法以编程方式进行访问。

其他参数与通过此菜单项导航到的组件相关,并且包含与该组件的输出如何在此特定网页上显示相关的属性。要查找这些内容,请找到保存该特定页面的布局文件的文件夹中的 .xml 文件。例如,对于显示单个联系方式的页面,请在 components/com_contact/tmpl/contact/ 中查找。

获取单个菜单项

除了上面介绍的用于筛选菜单项的机制,还有一些方法可以让你直接获得某些菜单项。

激活菜单项

站点的激活菜单项关系到 Joomla 用于确定页面展示的菜单项(例如,使用为菜单项定义的模板样式)。要找到该菜单项,请使用

use Joomla\CMS\Factory;
$app = Factory::getApplication();
$sitemenu = $app->getMenu();
$activeMenuitem = $sitemenu->getActive();

然后,你可以按上述说明获取此菜单项的属性和参数。

但是,请注意,在某些情况下未设置激活菜单项(当获得 /component/com_xxx 形式的 SEF 网址时)。

默认菜单项

例如,要查找某个语言的默认菜单项,请使用

$menuitem = $sitemenu->getItem($itemid);

(当你查看管理员后端的菜单项列表时,这正是带有国家/地区标志的菜单项。)

设置菜单项

例如,你可以使用以下代码设置菜单项属性和参数

$menuitem->setParams($params)     //set the params values

$sitemenu->setActive($itemid) // set the active menu item

或者通过简单地向菜单项 public 属性分配不同的值。但是,这些更改不会保存到数据库中,只会持续处理当前 HTTP 请求的时间。

示例模块代码

下面是简单 Joomla 模块的代码,你可以安装并运行此代码以演示如何使用菜单项 API 功能。

在 mod_sample_menu 文件夹中创建以下 2 个文件

mod_sample_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
<name>Menu demo</name>
<version>1.0.1</version>
<description>Code demonstrating use of Joomla APIs related to Menus and Menu Items</description>
<files>
<filename module="mod_sample_menu">mod_sample_menu.php</filename>
</files>
</extension>

mod_sample_menu.php

<?php
defined('_JEXEC') or die('Restricted Access');

use Joomla\CMS\Factory;

$app = Factory::getApplication();
$input = $app->input;

$sitemenu = $app->getMenu();

if ($activeMenuitem = $sitemenu->getActive())
{
echo "Active menuitem is Itemid: {$activeMenuitem->id}<br>";
}
else
{
echo "No active menuitem<br>";
}

if ($input->exists('menulanguage'))
{
$lang = $input->get('menulanguage', "", "STRING");
}
else
{
$lang = $app->getLanguage()->getTag();
}
echo "Getting details for language {$lang}<br>";

$menuitems = $sitemenu->getItems(array("language"), array($lang));

echo "<br>---- properties of menuitems ----<br>";
foreach ($menuitems as $menuitem)
{
echo "<br>Itemid: {$menuitem->id}, title: {$menuitem->title}, type: {$menuitem->type}<br>";
echo "<br>Language: {$menuitem->language}, level: {$menuitem->level}<br>";
$params = $menuitem->getParams();
if (!($displayed = $params->get("menu_show")))
{
echo "This menu item is hidden<br>";
}
if ($img = $params->get("menu_image"))
{
$imgURL = JURI::root() . $img;
echo "Image: {$img}<br><img src='{$imgURL}'><br>";
}
}

mod_sample_menu 目录压缩为 mod_sample_menu.zip

在 Joomla 管理员中,转到“安装扩展”,然后通过“上传包文件”选项卡选择此 zip 文件以安装此示例菜单模块。

编辑该模块使其可见(在“模块”页面中单击它),然后

  • 设其状态为“已发布”
  • 为其选择一个页面位置以显示模块
  • 在菜单分配选项卡中,指定模块应显示的页面

当访问某个网站页面时,你应在选定的位置看到该模块,模块应显示

  • 当前激活菜单项的 Itemid
  • 已使用当前语言的一组菜单项相关属性,
  • param 中的一些属性(显示菜单项是否隐藏以及与菜单项关联的任何图像)。

您可以通过添加 URL 参数(例如 ?menulanguage=fr-FR)使其显示其他语言的属性和参数。