iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0

Day 15 裝潢大廳,套用 Template 版面

想要裝潢的好看,可能自己動手會很困難,從視覺設計到 HTML 與 CSS如果通通自己從零開始,可能寫到 Day 30 都還沒刻完呢。其實想要找到別人做好的版面並不困難,github 就有許多人提供了開源的公用模板來讓大家使用,本系列文章會使用以下模板來進行範例:

https://github.com/themefisher/aviato

此模板有非常豐富的組件,礙於篇幅我們不會全部都進行實作,大家可以先跟著本系列文實作後再根據自己的需求繼續延伸,現在就讓我們開始吧!

建立靜態檔案目錄

首先我們要建立靜態檔案目錄,在 products 應用程式目錄建立 static 目錄,並在其中再建立一個 products 目錄。

接著我們要將公用模板下載下來(建議使用 git clone),並將 aviato/theme 目錄底下的 css、images、js、plugins 四個目錄放到 static 目錄底下,最後 products 應用程式的目錄結構如下:

.
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   ├── 0001_initial.py
│   └── __init__.py
├── models.py
├── static
│   └── products
│       ├── css
│       ├── images
│       ├── js
│       └── plugins
├── templates
│   └── products
│       ├── detail.html
│       ├── home.html
│       └── list.html
├── tests.py
├── urls.py
└── views.py

套用 HTML

我們將要使用新的頁面取代原本的首頁 home.html,將 aviato/index.html 更名為 home.html 並取代 products 應用程式目錄中的 template/products/home.html
我們將會刪減部分內容並套用以下幾個區塊,分別是 top-header、product-category section、products section bg-gray、footer section text-center。

在 Template 要讀取 static 目錄的檔案,需要讀取 static 標籤

{% load static %}

假設我們要取得 css/style.css 檔案,需要調整 html 頁面中匯入的連結,以下為範例:

<link rel="stylesheet" href="css/style.css">

調整為

<link rel="stylesheet" href="{% static 'products/css/style.css' %}">

不只是 css,只要 html 頁面中有使用到 static 目錄底下的檔案,都需要改為使用 static 標籤語法,

調整 static 標籤後的 home.html 如下(區塊內容先省略):

<!-- products/templates/products/home.html -->
{% load static %}
<!DOCTYPE html>

<html lang="zh-hant">
<head>

<!-- Basic Page Needs
================================================== -->
<meta charset="utf-8">
<title>IvanKao | E-commerce </title>

<!-- Mobile Specific Metas
================================================== -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="Construction Html5 Template">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<meta name="author" content="Themefisher">
<meta name="generator" content="Themefisher Constra HTML Template v1.0">

<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="{% static 'products/images/favicon.png' %}">

<!-- Themefisher Icon font -->
<link rel="stylesheet" href="{% static 'products/plugins/themefisher-font/style.css' %}">
<!-- bootstrap.min css -->
<link rel="stylesheet" href="{% static 'products/plugins/bootstrap/css/bootstrap.min.css' %}">

<!-- Animate css -->
<link rel="stylesheet" href="{% static 'products/plugins/animate/animate.css' %}">
<!-- Slick Carousel -->
<link rel="stylesheet" href="{% static 'products/plugins/slick/slick.css' %}">
<link rel="stylesheet" href="{% static 'products/plugins/slick/slick-theme.css' %}">

<!-- Main Stylesheet -->
<link rel="stylesheet" href="{% static 'products/css/style.css' %}">

</head>

<body id="body">

<!-- Start Top Header Bar -->
<section class="top-header">
    <div class="container">
        <!-- ...  -->
    </div>
</section><!-- End Top Header Bar -->

<section class="product-category section">
    <div class="container">
        <div class="row">
            <!-- ...  -->
        </div>
    </div>
</section>

<section class="products section bg-gray">
    <div class="container">
        <!-- ...  -->
    </div>
</section>

<footer class="footer section text-center">
    <div class="container">
        <!-- ...  -->
    </div>
</footer>

    <!-- 
    Essential Scripts
    =====================================-->
    
    <!-- Main jQuery -->
    <script src="{% static 'products/plugins/jquery/dist/jquery.min.js' %}"></script>
    <!-- Bootstrap 3.1 -->
    <script src="{% static 'products/plugins/bootstrap/js/bootstrap.min.js' %}"></script>
    <!-- Bootstrap Touchpin -->
    <script src="{% static 'products/plugins/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js' %}"></script>
    <!-- Instagram Feed Js -->
    <script src="{% static 'products/plugins/instafeed/instafeed.min.js' %}"></script>
    <!-- Video Lightbox Plugin -->
    <script src="{% static 'products/plugins/ekko-lightbox/dist/ekko-lightbox.min.js' %}"></script>
    <!-- Count Down Js -->
    <script src="{% static 'products/plugins/syo-timer/build/jquery.syotimer.min.js' %}"></script>

    <!-- slick Carousel -->
    <script src="{% static 'products/plugins/slick/slick.min.js' %}"></script>
    <script src="{% static 'products/plugins/slick/slick-animation.min.js' %}"></script>

    <!-- Google Mapl -->
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCC72vZw-6tGqFyRhhg5CkF2fqfILn2Tsw"></script>
    <script type="text/javascript" src="{% static 'products/plugins/google-map/gmap.js' %}"></script>

    <!-- Main Js File -->
    <script src="{% static 'products/js/script.js' %}"></script>
    

</body>
</html>

讓我們來看看呈現的效果,還挺不錯的對吧?

https://ithelp.ithome.com.tw/upload/images/20220927/20151656UcDy5vBoTI.png

建立基底頁面

不論是首頁、商品列表頁面、商品詳細頁面都會需要 頁首(header)與 頁尾(footer)兩個區塊,在 Django Template 有著特殊機制,可以透過 block 和 extends 來進行繼承,有效的減少重複的 HTML 程式碼。

我們將在 products 的 template 目錄建立一個 base.html ,將會包含 html 的框架、頁首、頁尾。

在不同頁面會變換的內容則使用 DTL 的 block 語法新增一個 context 區塊

<!-- products/templates/base.html -->
{% load static %}
<!DOCTYPE html>

<html lang="zh-hant">
<head>

<!-- Basic Page Needs
================================================== -->
<meta charset="utf-8">
<title>IvanKao | E-commerce </title>

<!-- Mobile Specific Metas
================================================== -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="Construction Html5 Template">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<meta name="author" content="Themefisher">
<meta name="generator" content="Themefisher Constra HTML Template v1.0">

<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="{% static 'products/images/favicon.png' %}">

<!-- Themefisher Icon font -->
<link rel="stylesheet" href="{% static 'products/plugins/themefisher-font/style.css' %}">
<!-- bootstrap.min css -->
<link rel="stylesheet" href="{% static 'products/plugins/bootstrap/css/bootstrap.min.css' %}">

<!-- Animate css -->
<link rel="stylesheet" href="{% static 'products/plugins/animate/animate.css' %}">
<!-- Slick Carousel -->
<link rel="stylesheet" href="{% static 'products/plugins/slick/slick.css' %}">
<link rel="stylesheet" href="{% static 'products/plugins/slick/slick-theme.css' %}">

<!-- Main Stylesheet -->
<link rel="stylesheet" href="{% static 'products/css/style.css' %}">

</head>

<body id="body">

<!-- Start Top Header Bar -->
<section class="top-header">
    <div class="container">
        <!-- ...  -->
    </div>
</section><!-- End Top Header Bar -->

{% block content %}
{% endblock content %}

<footer class="footer section text-center">
    <div class="container">
        <!-- ...  -->
    </div>
</footer>

    <!-- 
    Essential Scripts
    =====================================-->
    
    <!-- Main jQuery -->
    <script src="{% static 'products/plugins/jquery/dist/jquery.min.js' %}"></script>
    <!-- Bootstrap 3.1 -->
    <script src="{% static 'products/plugins/bootstrap/js/bootstrap.min.js' %}"></script>
    <!-- Bootstrap Touchpin -->
    <script src="{% static 'products/plugins/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js' %}"></script>
    <!-- Instagram Feed Js -->
    <script src="{% static 'products/plugins/instafeed/instafeed.min.js' %}"></script>
    <!-- Video Lightbox Plugin -->
    <script src="{% static 'products/plugins/ekko-lightbox/dist/ekko-lightbox.min.js' %}"></script>
    <!-- Count Down Js -->
    <script src="{% static 'products/plugins/syo-timer/build/jquery.syotimer.min.js' %}"></script>

    <!-- slick Carousel -->
    <script src="{% static 'products/plugins/slick/slick.min.js' %}"></script>
    <script src="{% static 'products/plugins/slick/slick-animation.min.js' %}"></script>

    <!-- Google Mapl -->
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCC72vZw-6tGqFyRhhg5CkF2fqfILn2Tsw"></script>
    <script type="text/javascript" src="{% static 'products/plugins/google-map/gmap.js' %}"></script>

    <!-- Main Js File -->
    <script src="{% static 'products/js/script.js' %}"></script>
    

</body>
</html>

有了基底頁面,我們的首頁 home.html 就可以不必重複所有程式碼,

使用 DTL 的 extends 語法繼承基底頁面,再調整 content 區塊的內容就可以了,以下是調整後的首頁:

{% extends "base.html" %}
{% load static %}
<section class="product-category section">
    <div class="container">
        <div class="row">
            <!-- ...  -->
        </div>
    </div>
</section>

<section class="products section bg-gray">
    <div class="container">
        <!-- ...  -->
    </div>
</section>
{% block content %}

繼承完成!

套版基本觀念就介紹到這裡,接著還需要取用資料與套用其他頁面,我們明天繼續『佈置房間, 將資料傳入 Template 』。


上一篇
Day 14 貼上照片牆,Django 多租戶圖片上傳
下一篇
Day 16 佈置房間, 將資料傳入 Template
系列文
全能住宅改造王,Django 多租戶架構的應用 —— 實作一個電商網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
terrytsang0618
iT邦新手 5 級 ‧ 2022-12-18 21:11:00

我有一些問題想問一下
在set up static folder的時候,
我是需要在setting.py加column嗎?
我加了這句才可以正常顯示,這樣改對嗎?
STATIC_ROOT = os.path.join(BASE_DIR, 'products/static')

另外想問一下
請問static folder放置在/opt/app/web/products 的path
和放置在/opt/app/web 的path
在setting.py會有分別嗎?
另外放在/products中的話其他apps可以應用嗎?

我要留言

立即登入留言