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
相关产品推荐
相关产品推荐

