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

Moodle插件开发:无法在index.php中显示HTML标题

Moodle本地插件自定义HTML无法显示问题排查与修复

问题描述

在Moodle部署环境中,我在mysitename/local/myfolder/index.php路径下编写了代码,实现学生登录后展示其选修的所有Moodle课程功能,核心功能正常,但添加的顶部红色标题“My Dash”这类简单HTML内容无法显示,请问问题出在哪里?

原代码

<?php

require_once(__DIR__ . '/../../config.php');

require_login();

$PAGE->set_context(context_system::instance());
$PAGE->set_title('Dashboard');
$PAGE->set_heading('Dashboard');
$PAGE->navbar->add('Dashboard');
echo $OUTPUT->header();

global $USER, $DB;

$courses = enrol_get_users_courses($USER->id);

echo '<!DOCTYPE html>';
echo '<html>';
echo '<head>';
echo '<title>My Dashboard</title>';
echo '<style>';
echo 'h1 { color: red; font-weight: bold; }';
echo '</style>';
echo '</head>';
echo '<body>';
echo '<h1>My Dash</h1>';

if ($courses) {
    echo '<h2>Your courses:</h2>';
    echo '<ul>';
    foreach ($courses as $course) {
        echo '<li><a href="' . $CFG->wwwroot . '/course/view.php?id=' . $course->id . '">' . $course->fullname . '</a></li>';

        // Get quizzes for the current course
        $quizzes = $DB->get_records_sql('SELECT q.id, q.name
                                         FROM {quiz} q
                                         INNER JOIN {course_modules} cm ON q.id = cm.instance
                                         INNER JOIN {modules} m ON m.id = cm.module
                                         WHERE cm.course = ? AND m.name = ?', [$course->id, 'quiz']);

        if ($quizzes) {
            echo '<ul>';
            foreach ($quizzes as $quiz) {
                $attempt = $DB->get_record_sql('SELECT a.*
                                                FROM {quiz_attempts} a
                                                WHERE a.quiz = ? AND a.userid = ?', [$quiz->id, $USER->id]);

                if (!$attempt) {
                    echo '<li>Quiz: <a href="' . $CFG->wwwroot . '/mod/quiz/view.php?id=' . $quiz->id . '">' . $quiz->name . '</a> (not taken)</li>';
                }
            }
            echo '</ul>';
        }

        // Get assignments for the current course
        $assignments = $DB->get_records_sql('SELECT a.id, a.name
                                              FROM {assign} a
                                              INNER JOIN {course_modules} cm ON a.id = cm.instance
                                              INNER JOIN {modules} m ON m.id = cm.module
                                              WHERE cm.course = ? AND m.name = ?', [$course->id, 'assign']);

        if ($assignments) {
            echo '<ul>';
            foreach ($assignments as $assignment) {
                $submission = $DB->get_record_sql('SELECT s.*
                                                    FROM {assign_submission} s
                                                    WHERE s.assignment = ? AND s.userid = ?', [$assignment->id, $USER->id]);

                if (!$submission) {
                    echo '<li>Assignment: <a href="' . $CFG->wwwroot . '/mod/assign/view.php?id=' . $assignment->id . '">' . $assignment->name . '</a> (not submitted)</li>';
                }
            }
            echo '</ul>';
        }
    }
    echo '</ul>';
} else {
    echo '<p>You are not enrolled in any courses</p>';
}

echo '</body>';
echo '</html>';

echo $OUTPUT->footer();

问题根源

你犯了Moodle开发的典型错误:

  • 调用echo $OUTPUT->header();后,Moodle已经自动生成了完整的HTML文档结构(包括<html>、<head>、<body>标签),但你后续又手动输出了一套完整的HTML结构,导致浏览器解析混乱,自定义标题被嵌套在错误的DOM位置,最终被忽略或无法正常渲染。
  • 手动输出的<title>标签会覆盖之前通过$PAGE->set_title()设置的标题,破坏Moodle的主题一致性。

修复方案

修改后的代码

<?php

require_once(__DIR__ . '/../../config.php');

require_login();

$PAGE->set_context(context_system::instance());
$PAGE->set_title('Dashboard');
$PAGE->set_heading('Dashboard');
$PAGE->navbar->add('Dashboard');

// 方式1:引用外部CSS文件(推荐,便于维护)
$PAGE->requires->css(new moodle_url('/local/myfolder/styles.css'));

// 方式2:添加内联样式(快速测试用)
// $PAGE->requires->css_inline('h1 { color: red; font-weight: bold; }');

echo $OUTPUT->header();

global $USER, $DB;

$courses = enrol_get_users_courses($USER->id);

// 直接输出内容,无需手动构建HTML框架
echo '<h1>My Dash</h1>';

if ($courses) {
    echo '<h2>你的课程:</h2>';
    echo '<ul>';
    foreach ($courses as $course) {
        echo '<li><a href="' . $CFG->wwwroot . '/course/view.php?id=' . $course->id . '">' . $course->fullname . '</a></li>';

        // 获取课程中的测验
        $quizzes = $DB->get_records_sql('SELECT q.id, q.name
                                         FROM {quiz} q
                                         INNER JOIN {course_modules} cm ON q.id = cm.instance
                                         INNER JOIN {modules} m ON m.id = cm.module
                                         WHERE cm.course = ? AND m.name = ?', [$course->id, 'quiz']);

        if ($quizzes) {
            echo '<ul>';
            foreach ($quizzes as $quiz) {
                $attempt = $DB->get_record_sql('SELECT a.*
                                                FROM {quiz_attempts} a
                                                WHERE a.quiz = ? AND a.userid = ?', [$quiz->id, $USER->id]);

                if (!$attempt) {
                    echo '<li>测验: <a href="' . $CFG->wwwroot . '/mod/quiz/view.php?id=' . $quiz->id . '">' . $quiz->name . '</a> (未完成)</li>';
                }
            }
            echo '</ul>';
        }

        // 获取课程中的作业
        $assignments = $DB->get_records_sql('SELECT a.id, a.name
                                              FROM {assign} a
                                              INNER JOIN {course_modules} cm ON a.id = cm.instance
                                              INNER JOIN {modules} m ON m.id = cm.module
                                              WHERE cm.course = ? AND m.name = ?', [$course->id, 'assign']);

        if ($assignments) {
            echo '<ul>';
            foreach ($assignments as $assignment) {
                $submission = $DB->get_record_sql('SELECT s.*
                                                    FROM {assign_submission} s
                                                    WHERE s.assignment = ? AND s.userid = ?', [$assignment->id, $USER->id]);

                if (!$submission) {
                    echo '<li>作业: <a href="' . $CFG->wwwroot . '/mod/assign/view.php?id=' . $assignment->id . '">' . $assignment->name . '</a> (未提交)</li>';
                }
            }
            echo '</ul>';
        }
    }
    echo '</ul>';
} else {
    echo '<p>你尚未选修任何课程</p>';
}

echo $OUTPUT->footer();

关键修改点

  • 移除重复HTML结构:删除手动输出的<!DOCTYPE html>、<html>、<head>、<body>标签,Moodle的$OUTPUT->header()和$OUTPUT->footer()已经负责生成符合规范的页面框架。
  • 正确注入样式:通过Moodle的$PAGE->requires对象添加CSS,优先使用外部CSS文件(需在local/myfolder下创建styles.css文件),确保样式被正确加载到页面头部。
  • 遵循Moodle渲染流程:所有自定义内容直接输出在$OUTPUT->header()和$OUTPUT->footer()之间,保持与Moodle主题的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:19:59