Marco de secciones del curso
- Impacto — Tema: SCSS nuevo
scss/coursesections.scss, registrado entheme_cdigital_get_main_scss_content()(lib.php) - Impacto — Plugin: —
- Requisito: Lógica Dashboard / Panel aprendizaje (xlsx) · Figma:
19723-2794,19756-3011· Estado: Implementado
Propósito
Restyle de las secciones del curso (/course/view.php) para que cada una se presente como un
acordeón de borde redondeado con cabecera sombreada, siguiendo el nodo de Figma
Table_acordeon (19723-2794), reutilizado seis veces en la vista de curso 19723-2726. Extiende
también a la vista de una sola sección (coursedisplay = mostrar una sección por página, Figma
19756-3011): tarjeta "héroe" de sección (carátula, progreso) y navegación anterior/siguiente
sección, con datos reales de course_stats.
Alcance
- Aplica dentro de
id="page-content"— el límite acordado para todo el "contenido interno de curso" (ver también Marco del contenido de actividad, que extiende el mismo lenguaje amod/*/view.php). No alcanza al cajón de bloques (side-pre), la fila de hero de curso, el banner ni la miga de pan, que ya tienen su propio restyle (ver Fila "Contenido del curso" + insignias, Banner "Tu desempeño académico", Drawer "Índice de curso"). - Alcanza a los formatos que apilan secciones con el contrato de marcado de
core_courseformat:topics,weeks,grid(hereda ese contrato vía{{< core_courseformat/local/content/section }}) y secciones delegadas (core_courseformat/local/content/delegatedsection.mustache). - No alcanza a
format_onetopic: sus secciones se navegan como pestañas, no como acordeones apilados, y su plantilla no emite.section-item. Ya tiene su propio restyle en Pestañas de secciones del curso (format_onetopic). - Profundidad del acordeón de listado: marco, cabecera sombreada y chevron de plegado. Quedan
fuera el chip de ícono junto al título y la etiqueta "X de Y actividades" por fila del Figma,
así como el rediseño de las filas de actividad (columna de descripción y botón
Completado/Continuar/Pendiente). La etiqueta "N de M actividades" y el ícono decorativo sí
están resueltos en la tarjeta "héroe" de la vista de una sola sección (ver abajo), que reutiliza
course_stats::get_user_module_progress()para ese dato.
Desviaciones conscientes
- Chevron rotatorio en vez de fijo: el Figma dibuja el chevron apuntando siempre hacia arriba
(dibuja el estado expandido). Aquí rota entre expandido (arriba) y plegado (abajo), reutilizando
el mismo mecanismo
.icons-collapse-expand/.collapsedque ya usa el drawer de índice de curso (scss/courseindex.scss). - Cabecera completa clicable: el Figma la dibuja como un
<button>. Se añade un overlay sobre el toggler nativo (a.icons-collapse-expand::after), activo solo fuera de modo edición: en edición el área debe quedar libre para el arrastre de secciones/actividades, el checkbox de selección múltiple y el menú de acciones de sección. format_onetopicfuera de alcance, y con él, el curso piloto (id 3) y el de la biblioteca escolar (id 5): sus secciones siguen siendo pestañas.- Formato con una sección por página (
coursedisplay= mostrar una sección por página, p. ej. el curso de evaluación en modo grid): el marco y la cabecera sombreada de la tabla de actividades se aplican igual, pero sin chevron ni plegado — en ese modo Moodle no emite el toggler y el cuerpo no es colapsable; la cabecera vacía se oculta por completo (ver "Detalles técnicos"). - Navegación anterior/siguiente sección con leyenda de dos líneas: a diferencia de la
navegación de actividad (ver Marco del contenido de actividad),
aquí SÍ se construye "Módulo anterior"/"Siguiente módulo" + nombre en dos líneas, porque es una
plantilla enteramente propia del tema (
theme_cdigital/section_navigation_row), no una sobrescritura de la plantilla decore_courseformat— no acarrea el mismo riesgo de resincronización en upgrade. - La carátula de la tarjeta "héroe" reutiliza la imagen del curso, no una imagen propia de la
sección: Moodle no tiene ese concepto en su modelo de datos, y las imágenes por sección que
administra
format_gridpara sus mosaicos viven en almacenamiento propio del plugin sin API pública — depender de eso para un detalle cosmético quedó fuera de alcance.
Arquitectura
El marcado del acordeón de listado lo emite core_courseformat y es estable en el contrato entre
plantillas (.section-item, .course-section-header, data-for="section_title" /
"sectiontoggler"), no clases puramente presentacionales de Bootstrap. Por eso, igual que en
Pestañas de secciones (format_onetopic) y la
miga de pan (ADR-005), no
se sobrescribe ninguna plantilla: las de core_courseformat cambian entre versiones de Moodle y
obligarían a resincronizar en cada upgrade.
#region-main
└─ .course-content
└─ ul.section-list
└─ li.course-section.main
└─ div.section-item ← marco (borde 1px, radio 16)
├─ div.course-section-header ← cabecera sombreada (#f3f5fd)
│ └─ a.icons-collapse-expand + h.sectionname
└─ div.content.collapse ← cuerpo
La tarjeta "héroe" y la navegación de sección, en cambio, son plantillas propias del tema
(mismo patrón que course_hero_row.mustache/continue_card.mustache), inyectadas desde
core_renderer::full_header() y core_renderer::course_content_footer() cuando
single_section_num() detecta coursedisplay == COURSE_DISPLAY_MULTIPAGE — sin depender del
estado interno cacheado del course_format (lee el parámetro section de la URL directamente, ya
que el orden de renderizado no garantiza que set_sectionnum() ya se haya llamado). El resumen de
la tarjeta y la navegación reutilizan las clases estables de core
(core_courseformat\output\local\content\section\summary,
core_courseformat\output\local\content\sectionnavigation) en vez de recalcular esos datos —
get_output_classname() resuelve automáticamente a la versión de format_grid cuando aplica, sin
que el tema necesite distinguir el formato.
Detalles técnicos
- Cabecera vacía en vista de una sola sección:
core_courseformat/local/content/section/header.mustacheno emite título ni chevron cuandodisplayonesectiones verdadero (ambas ramas quedan detrás de{{^displayonesection}}), perodata-region="sectionbadges"sí se sigue emitiendo siempre, así que.course-section-headerno queda realmente vacío como para usar:empty. Se detecta con:not(:has(.sectionname))y se colapsa porheight/padding/border/overflowen vez dedisplay: none— verificado en vivo que undisplay: none !importantno ganaba la pelea contra eldisplay: flex !importantde la utilidad Bootstrap.d-flexen este archivo compilado concreto, mientras que las propiedades que.d-flexno toca sí se aplican sin necesitar!important. :has()no admite anidarse dentro de otro:has(), ni siquiera a través de:not()(lo prohíbe la especificación de Selectors Level 4; un selector así es inválido y el navegador descarta la regla completa). El resumen duplicado del cuerpo de la sección ([data-for="sectioninfo"], que de otro modo repetiría el mismo texto que ya muestra la tarjeta "héroe") se oculta con un combinador de hermanos (.course-section-header:not(:has(.sectionname)) + .content [data-for="sectioninfo"]) en vez de envolver.section-itemen un:has()que contuviera esa misma condición.
Archivos del tema involucrados
| Archivo | Función |
|---|---|
scss/mixins.scss | @mixin cdigital-chevron-toggle() — mecanismo de chevron plegable compartido con scss/courseindex.scss y scss/activitypage.scss; se concatena primero |
scss/coursesections.scss | Marco y cabecera del acordeón de listado; cabecera vacía en vista de una sola sección; tarjeta "héroe" (.cdigital-sectionhero*) y navegación de sección (.cdigital-sectionnav*) |
templates/section_hero_row.mustache | Tarjeta "héroe" (carátula, nombre, progreso) + tarjeta de resumen |
templates/section_navigation_row.mustache | Navegación "Módulo anterior"/"Siguiente módulo" |
classes/output/core_renderer.php | single_section_num(), section_hero_row_context(), section_navigation_context(); override de full_header() y course_content_footer() |
lib.php | theme_cdigital_get_main_scss_content() — registra scss/mixins.scss primero y scss/coursesections.scss después de scss/coursetabs.scss |
Build y despliegue
Solo SCSS: no requiere build de AMD (grunt). Basta con purgar cachés tras el despliegue — ver
Procedimiento de despliegue.
Historial de cambios
Ver CHANGELOG.md en la raíz del sitio de documentación.