在網頁的第二部分,因為重複的 HTML 會一直出沒,會以迴圈為核心進行編寫:
在這裡會用到幾個很重要的觀念:
{{ }}
在上一篇有提到 {{ }}
是一種 Django 所特有的 Variable tag,兩個花括號代表的是一個變數,在之後會密集的出現這類型的 tag,目的讓由後端傳值至前端時能動態代入至 HTML。
例如:
<div class="card-footer text-muted">
投稿:{{ each_feedback.submitter_name }} {{ each_feedback.last_updated_time }}
</div>
{% %}
{% %}
則是 Template tag 語法/模板標籤,因 HTML 不具有邏輯設計,常被調侃不是程式語言,可以加入 for 迴圈或 if 條件句根據情況顯示的 HTML 內容。
例如:
{% for each_feedback in feedback %}
<!-- 每則評價的 HTML -->
{% endfor %}
如果使用了 {% for each_feedback in feedback %}
搭配 {% endfor %}
進行迴圈的 HTML 呈現,就能夠使用 {{forloop.counter}}
去判斷現在是第 N 個元素,能夠當作 id
屬性進行後續 Js 處理。而當變數內其實沒有內容時, {% empty %}
也可以作為無內容的 HTML 顯示。
例如:
{% for each_feedback in feedback %}
<span class="collapse" id="collapse-each_feedback-{{ forloop.counter }}">
<!-- 每則評價的 HTML -->
{% empty %}
<p class="text-center">沒有符合的評價結果。</p>
{% endfor %}
|
模板過濾器也是很酷的功能,若是變數很長 (像是評價肉肉長),就能使用 | slice:":200"
或 | slice:"200:"
顯示前 200 字或後 200 字,適合用於展開折疊內容用途。| linebreaksbr
會將文本中的換行符 \n
替換為 <br />
標籤,這樣換行符在 HTML 中會正確顯示為換行效果。
例如要將評價內容顯示後 200 字:
{{ each_feedback.feedback_content|slice:"200:"|linebreaksbr }}
Bootstrap 也提供 Icons 庫可以讓開發者選擇不一樣酷酷的圖案,除了以字體方式引入 Icon 外,也能使用 SVG
方式貼上:
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-arrows-expand" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M1 8a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13A.5.5 0 0 1 1 8M7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10" />
</svg>
完整的評價顯示內容:
<!-- 使用 Django template tag 顯示單頁最多十則評價 -->
<div class="row">
<!-- 利用迴圈顯示後端 feedback 所含有的各個課程資訊 -->
{% for each_feedback in feedback %}
<div class="col-md-4 mt-3 d-flex">
<div class="card mb-4 h-100">
<div class="card-header">
<!-- 顯示單一個 each_feedback 的特定內容 -->
{{ each_feedback.teacher_name }}-{{ each_feedback.course_name }}
</div>
<div class="card-body">
<p class="card-text">
<!-- 甚至可以決定顯示前 200 個字元,並允許以 br 換行 -->
{{ each_feedback.feedback_content|slice:":200"|linebreaksbr }}
<!-- forloop.counter 能提示出目前的元素是第幾個 -->
<span class="collapse" id="collapse-each_feedback-{{ forloop.counter }}">
{{ each_feedback.feedback_content|slice:"200:"|linebreaksbr }}
</p>
<button type="button" class="btn btn-sm btn-light" data-bs-toggle="collapse"
href="#collapse-each_feedback-{{ forloop.counter }}" role="button" aria-expanded="false"
aria-controls="collapse-each_feedback-{{ forloop.counter }}">
<!-- 這邊看起來像是亂碼的地方,其實是一個折疊的 icon -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-arrows-expand" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M1 8a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13A.5.5 0 0 1 1 8M7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10" />
</svg>
</button>
</div>
<div class="card-footer text-muted">
投稿:{{ each_feedback.submitter_name }} {{ each_feedback.last_updated_time }}
</div>
</div>
</div>
<!-- 當 for 迴圈發現內容為空時,則顯示無評價結果 -->
{% empty %}
<p class="text-center">沒有符合的評價結果。</p>
{% endfor %}
</div>
當後端以 Django 的 Paginator 使用時,前端就能以 paginator 模板標籤搭配 {% if %} {% endif %}
、{% for %}
{% endfor %}
進行渲染:
<!-- 分頁按鈕 -->
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
{% if feedback.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ feedback.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for num in feedback.paginator.page_range %}
<li class="page-item mt-3 {% if feedback.number == num %}active{% endif %}">
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
</li>
{% endfor %}
{% if feedback.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ feedback.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
</nav>
在這篇文章中,我們學會了: