Component System
Six component types for course content, parsed by markdown-it-container.
Overview
| Type | Color | Purpose | Aggregated |
|---|---|---|---|
homework |
Orange | Graded assignments | Yes |
exercise |
Cyan | Practice (ungraded) | No |
prompt |
Purple | LLM prompts with copy | No |
example |
Gray | Code/concept demos | No |
exam |
Red | Exam information | Yes |
project |
Yellow | Long-term projects | Yes |
Syntax
Basic Format
:::type{attr1="value1" attr2="value2"}
Content here (supports all markdown)
:::
Homework
:::homework{id="A.1.1" title="Task Name" due="2026-02-01" points="10"}
Instructions for the assignment.
:::
Attributes:
id(required): Unique identifiertitle(required): Display namedue(optional): Due date (YYYY-MM-DD)points(optional): Point value
Exercise
:::exercise{title="Exercise Title" difficulty="3"}
Step-by-step instructions.
:::
Attributes:
title(required): Display namedifficulty(optional): 1-5 scale (shown as asterisks)
Prompt
:::prompt{title="Prompt Name" for="ChatGPT"}
Prompt text to copy/paste into LLM.
:::
Attributes:
title(required): Display namefor(optional): Target LLM (ChatGPT, Claude, Cursor)
Example
:::example{title="Example Title"}
Example content with code:
```python
def hello():
print("Hello!")
:::
**Attributes:**
- `title` (required): Display name
- `language` (optional): Not currently used
### Exam
```markdown
:::exam{id="parcial-01" title="Primer Parcial" date="2026-03-15" location="Aula 201" duration="2 horas"}
Topics and exam information.
:::
Attributes:
id(required): Unique identifiertitle(required): Display namedate(optional): Exam datelocation(optional): Locationduration(optional): Duration
Project
:::project{id="proyecto-final" title="Final Project" due="2026-05-15" team_size="3" points="50"}
Project description and requirements.
:::
Attributes:
id(required): Unique identifiertitle(required): Display namedue(optional): Due dateteam_size(optional): Team sizepoints(optional): Point value
HTML Output
<div class="component component--homework" data-id="A.1.1" data-title="Task Name" data-due="2026-02-01">
<!-- Rendered markdown content -->
</div>
CSS Styling
Base Styles (main.css)
.component {
@apply p-4 rounded-lg mb-4;
border-left: 4px solid;
background: var(--color-bg-secondary);
}
.component::before {
@apply text-xs font-bold uppercase mb-2 block;
}
Per-Type Styles
.component--homework { border-color: var(--color-homework); }
.component--homework::before { content: '[TAREA]'; color: var(--color-homework); }
.component--exercise { border-color: var(--color-exercise); }
.component--exercise::before { content: '[EJERCICIO]'; color: var(--color-exercise); }
.component--prompt { border-color: var(--color-prompt); }
.component--prompt::before { content: '[PROMPT]'; color: var(--color-prompt); }
Nesting Rules
Allowed
- Markdown formatting (bold, italic, links)
- Code blocks (fenced with ```)
- Lists (ordered and unordered)
- Tables
- Headings (H2, H3, etc.)
Not Allowed
- Components inside components (nested containers)
- The inner
:::would be treated as literal text
Adding a New Component
Step 1: Update .eleventy.js
Add to componentTypes array (line 32):
const componentTypes = ['homework', 'exercise', 'prompt', 'example', 'exam', 'project', 'note'];
Step 2: Add CSS Styles
In main.css:
.component--note {
border-color: var(--color-note);
}
.component--note::before {
content: '[NOTA]';
color: var(--color-note);
}
Step 3: Add Theme Color
In each theme file (eva01.css, light.css):
--color-note: #17a2b8; /* Teal */
Step 4: Update Tailwind Safelist
In tailwind.config.js:
safelist: [
// ... existing
'text-note', 'border-note', 'bg-note/15',
]
Step 5 (Optional): Add Template
Create _includes/components/note.njk:
{% if note %}
<div class="component component--note">
<h3 class="font-bold text-note">{{ note.title }}</h3>
{{ note.content | safe }}
</div>
{% endif %}
Step 6 (Optional): Add Aggregation
In aggregate_tasks.py, add extraction logic.
Attribute Validation
Current Behavior
- Missing attributes: Empty string or
null - Invalid format: Silently ignored
- Duplicate IDs: Not detected
Best Practices
- Always quote attribute values:
id="value" - Use YYYY-MM-DD for dates
- Use alphanumeric IDs (no special characters)