Phase 2: T-201 至 T-206 前台 MVP 全部实现(11 templates + CSS + 31 tests)
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ page.title }}</h1>
|
||||
|
||||
{% if page.get_children.live %}
|
||||
<div class="card-grid">
|
||||
{% for article in page.get_children.live %}
|
||||
<a class="card" href="{% url 'wagtail_serve' '' %}articles/{{ article.slug }}/">
|
||||
<h3>{{ article.title }}</h3>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
{% include "includes/empty_state.html" with message="No articles yet." %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ page.title }}</h1>
|
||||
|
||||
<div class="rich-text">{{ page.body|safe }}</div>
|
||||
|
||||
{% if page.related_projects.exists %}
|
||||
<h2>Related Projects</h2>
|
||||
<div class="card-grid">
|
||||
{% for project in page.related_projects.all %}
|
||||
<a class="card" href="{% url 'wagtail_serve' '' %}projects/{{ project.slug }}/">
|
||||
<h3>{{ project.title }}</h3>
|
||||
<p>{{ project.summary|truncatewords:20 }}</p>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,85 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ page.title }}</h1>
|
||||
|
||||
<form class="filters" method="get">
|
||||
<label>
|
||||
Language:
|
||||
<select name="language">
|
||||
<option value="">All</option>
|
||||
{% for lang in languages %}
|
||||
<option value="{{ lang.slug }}" {% if current_language == lang.slug %}selected{% endif %}>{{ lang.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Framework:
|
||||
<select name="framework">
|
||||
<option value="">All</option>
|
||||
{% for fw in frameworks %}
|
||||
<option value="{{ fw.slug }}" {% if current_framework == fw.slug %}selected{% endif %}>{{ fw.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Database:
|
||||
<select name="database">
|
||||
<option value="">All</option>
|
||||
{% for db in databases %}
|
||||
<option value="{{ db.slug }}" {% if current_database == db.slug %}selected{% endif %}>{{ db.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Min Score:
|
||||
<input type="number" name="min_score" min="0" max="30" value="{{ current_min_score }}" style="width:5ch;">
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Search:
|
||||
<input type="text" name="q" value="{{ current_q }}" placeholder="Keyword...">
|
||||
</label>
|
||||
|
||||
<button type="submit">Filter</button>
|
||||
</form>
|
||||
|
||||
{% if projects %}
|
||||
<div class="card-grid">
|
||||
{% for project in projects %}
|
||||
<a class="card" href="{% url 'wagtail_serve' '' %}projects/{{ project.slug }}/">
|
||||
<h3>{{ project.title }}</h3>
|
||||
<p>{{ project.summary|truncatewords:20 }}</p>
|
||||
<div class="score-bar">
|
||||
<span class="score-total">{{ project.total_score }}/30</span>
|
||||
<span class="score-detail">AI-Friendly Score</span>
|
||||
</div>
|
||||
<div class="tag-list">
|
||||
{% for lang in project.languages.all|slice:":3" %}
|
||||
<span class="tag">{{ lang.name }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if projects.paginator.num_pages > 1 %}
|
||||
<nav class="pagination">
|
||||
{% if projects.has_previous %}
|
||||
<a href="?{% for k,v in request.GET.items %}{% if k != 'page' %}{{ k }}={{ v }}&{% endif %}{% endfor %}page={{ projects.previous_page_number }}">« Prev</a>
|
||||
{% endif %}
|
||||
<span class="current">Page {{ projects.number }} of {{ projects.paginator.num_pages }}</span>
|
||||
{% if projects.has_next %}
|
||||
<a href="?{% for k,v in request.GET.items %}{% if k != 'page' %}{{ k }}={{ v }}&{% endif %}{% endfor %}page={{ projects.next_page_number }}">Next »</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% include "includes/empty_state.html" with message="No projects match your filters." %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,29 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ page.title }}</h1>
|
||||
|
||||
{% if projects %}
|
||||
<div class="card-grid">
|
||||
{% for project in projects %}
|
||||
<a class="card" href="{% url 'wagtail_serve' '' %}projects/{{ project.slug }}/">
|
||||
<h3>{{ project.title }}</h3>
|
||||
<p>{{ project.summary|truncatewords:20 }}</p>
|
||||
<div class="score-bar">
|
||||
<span class="score-total">{{ project.total_score }}/30</span>
|
||||
<span class="score-detail">AI-Friendly Score</span>
|
||||
</div>
|
||||
<div class="tag-list">
|
||||
{% for lang in project.languages.all|slice:":3" %}
|
||||
<span class="tag">{{ lang.name }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
{% include "includes/empty_state.html" with message="No projects found in this scenario." %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,76 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<article>
|
||||
<h1>
|
||||
{{ page.title }}
|
||||
{% if page.is_featured %}<span class="badge badge-featured">Featured</span>{% endif %}
|
||||
{% if page.is_sponsored %}{% include "includes/sponsored_badge.html" %}{% endif %}
|
||||
</h1>
|
||||
|
||||
<p class="rich-text">{{ page.summary }}</p>
|
||||
|
||||
<table class="data-table">
|
||||
<tr><th>GitHub</th><td><a href="{{ page.github_url }}" target="_blank" rel="noopener">{{ page.github_url }}</a></td></tr>
|
||||
{% if page.official_url %}
|
||||
<tr><th>Official Site</th><td><a href="{{ page.official_url }}" target="_blank" rel="noopener">{{ page.official_url }}</a></td></tr>
|
||||
{% endif %}
|
||||
{% if page.license_name %}
|
||||
<tr><th>License</th><td>{{ page.license_name }}</td></tr>
|
||||
{% endif %}
|
||||
<tr><th>Maturity</th><td>{{ page.get_maturity_display }}</td></tr>
|
||||
<tr><th>Maintenance</th><td>{{ page.get_maintenance_status_display }}</td></tr>
|
||||
{% if page.scenarios.exists %}
|
||||
<tr><th>Scenarios</th><td>
|
||||
{% for s in page.scenarios.all %}<span class="tag">{{ s.title }}</span>{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
{% if page.languages.exists %}
|
||||
<tr><th>Languages</th><td>
|
||||
{% for l in page.languages.all %}<span class="tag">{{ l.name }}</span>{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
{% if page.frameworks.exists %}
|
||||
<tr><th>Frameworks</th><td>
|
||||
{% for f in page.frameworks.all %}<span class="tag">{{ f.name }}</span>{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
{% if page.databases.exists %}
|
||||
<tr><th>Databases</th><td>
|
||||
{% for d in page.databases.all %}<span class="tag">{{ d.name }}</span>{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
{% if page.features.exists %}
|
||||
<tr><th>Features</th><td>
|
||||
{% for feat in page.features.all %}<span class="tag">{{ feat.name }}</span>{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
<h2>Scores</h2>
|
||||
<table class="data-table">
|
||||
<tr><th>Structure</th><td>{{ page.structure_score }}/5</td></tr>
|
||||
<tr><th>Documentation</th><td>{{ page.docs_score }}/5</td></tr>
|
||||
<tr><th>Testing</th><td>{{ page.tests_score }}/5</td></tr>
|
||||
<tr><th>Examples</th><td>{{ page.example_score }}/5</td></tr>
|
||||
<tr><th>Dependency Control</th><td>{{ page.dependency_score }}/5</td></tr>
|
||||
<tr><th>Incremental Development</th><td>{{ page.incremental_score }}/5</td></tr>
|
||||
<tr><th>Total</th><td><strong>{{ page.total_score }}/30</strong></td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Recommended For</h2>
|
||||
<div class="rich-text">{{ page.recommended_for|safe }}</div>
|
||||
|
||||
{% if page.not_recommended_for %}
|
||||
<h2>Not Recommended For</h2>
|
||||
<div class="rich-text">{{ page.not_recommended_for|safe }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page.review_notes %}
|
||||
<h2>Review Notes</h2>
|
||||
<div class="rich-text">{{ page.review_notes|safe }}</div>
|
||||
{% endif %}
|
||||
</article>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user