想要裝潢的好看,可能自己動手會很困難,從視覺設計到 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
我們將要使用新的頁面取代原本的首頁 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>
讓我們來看看呈現的效果,還挺不錯的對吧?
不論是首頁、商品列表頁面、商品詳細頁面都會需要 頁首(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 』。
我有一些問題想問一下
在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可以應用嗎?