You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Moodle Boost子主题Theant渲染全站课程菜单的问题

问题解答

1. theme/theant/renderers.php 代码与位置分析

  • 位置正确:renderers.php 放在主题根目录下是Moodle主题的标准配置位置,无问题。
  • 代码存在以下问题:
    • 方法命名不符合Moodle渲染器设计逻辑:render_* 系列方法的作用是渲染组件并返回HTML,而你这里仅生成数据数组,并非直接渲染模板,命名混淆了用途。
    • 方法权限错误:protected 修饰的方法无法在外部(如布局文件)直接调用,你之前尝试的静态调用必然报错。
    • 未过滤系统课程:get_courses() 会返回包括站点首页(id=1)在内的所有课程,通常这不是需要展示的内容。
    • URL处理不当:直接返回moodle_url对象到Mustache模板,模板无法直接解析,需转为字符串形式的URL。

2. 正确渲染$allcourses_menu的步骤

方案一:直接在布局文件中处理数据(推荐,更简洁)

修改theme/theant/layout/column.php,在生成模板上下文时直接获取课程数据:

global $CFG;
require_once($CFG->dirroot.'/lib/datalib.php');

// 获取所有课程,排除系统默认站点课程(id=1)
$allcourses = get_courses('id', 'ASC', 'id, shortname', 'id != 1');
$allcourses_menu = [];

foreach ($allcourses as $course) {
    $allcourses_menu[] = [
        'coursename' => format_string($course->shortname), // 格式化课程名,避免XSS风险
        'courselink' => (new moodle_url('/course/view.php', ['id' => $course->id]))->out(false) // 转换为字符串URL
    ];
}

// 将数据加入模板上下文
$templatecontext = [
    // 保留原有上下文数据
    'allcourses_menu' => $allcourses_menu,
];

echo $OUTPUT->render_from_template('theme_theant/columns', $templatecontext);

方案二:通过渲染器提供数据(适合需要复用数据的场景)

先修正theme/theant/renderers.php代码:

class theme_theant_core_renderer extends \core_renderer {
    public function get_allcourses_menu() {
        global $CFG;
        require_once($CFG->dirroot.'/lib/datalib.php');
        
        // 过滤系统课程,仅获取用户可见课程
        $allcourses = get_courses('id', 'ASC', 'id, shortname', 'id != 1');
        $allcourses_menu = [];
        
        foreach ($allcourses as $course) {
            $allcourses_menu[] = [
                'coursename' => format_string($course->shortname),
                'courselink' => (new moodle_url('/course/view.php', ['id' => $course->id]))->out(false)
            ];
        }
        
        return $allcourses_menu;
    }
}

再在theme/theant/layout/column.php中调用渲染器方法:

// 通过$OUTPUT调用渲染器的公共方法
$allcourses_menu = $OUTPUT->get_allcourses_menu();

$templatecontext = [
    // 保留原有上下文数据
    'allcourses_menu' => $allcourses_menu,
];

echo $OUTPUT->render_from_template('theme_theant/columns', $templatecontext);

最后修正Mustache模板

打开theme/theant/templates/navbar.mustache,去掉课程名两侧多余的引号:

<nav class="fixed-top navbar navbar-bootswatch navbar-expand moodle-has-zindex">
    <div class="fixed-subtop navbar" style="background-color: #333333; color: white;">
        <ul>
            {{#allcourses_menu}}
                <li><a href="{{courselink}}">{{coursename}}</a></li>
            {{/allcourses_menu}}
        </ul>
    </div>
</nav>

内容的提问来源于stack exchange,提问作者phchon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:42:49