มาหัดเขียนบล็อคด้วย Middleman ตอนที่ 3 (Partials Template)

มาหัดเขียนบล็อคด้วย Middleman ตอนที่ 3 (Partials Template) Cover Image

Table of Contents

หลักจากจบ Part 2 ไปแล้ว เราจะได้หน้า index แบบ Clean Blog แต่ว่ายังไม่มีหน้า Post รวมถึง ไฟล์ต่างๆ ก็ยังดูและจัดการค่อนข้างยาก สำหรับ Part 3 จะพูดถึง Partials Template ซึ่งจะช่วยให้เราแบ่งแยกไฟล์ต่างๆ ออกเป็นส่วนๆ เพื่อให้ง่ายต่อการเขียน เช่น แยกส่วน header, navbar, footer เป็นต้น

Partials Template

การใช้งาน Partials Template ใน Middleman ก็มี syntax ง่ายๆ ดังนี้

<%= partial "path/to/file" %>

ตัวอย่าง จะทำการสร้างโฟลเดอร์ใหม่ ขึ้นมาให้ชื่อว่า partials อยู่ภายในโฟลเดอร์ source และไฟล์ต่างๆ ที่เราต้องการจะแบ่งส่วน ก็จะเซฟไว้ในโฟลเดอร์นี้ เช่น partials/_header.erb , partials/_footer.erb เป็นต้น (ขึ้นต้นด้วย _)

คราวนี้ลองเปิดไฟล์ layout.erb ซึ่งไฟล์ยาวมากๆ แต่เราสามารถแบ่งส่วนมันได้ จนทำให้ตอนนี้ไฟล์ layout.erb เหลือแค่นี้

<%= partial "partials/header" %>

<body>

    <%= partial "partials/navbar" %>

    <%= yield %>

    <%= partial "partials/footer" %>
    <!-- jQuery -->
    <%= javascript_include_tag "jquery" %>
    <!-- Bootstrap Core JavaScript -->
    <%= javascript_include_tag "bootstrap.min" %>
    <!-- Custom Theme JavaScript -->
    <%= javascript_include_tag "clean-blog.min" %>

</body>

</html>

ส่วนอื่นๆ ก็จะถูกแยก ออกไปเซฟไว้แต่ละส่วน เพื่อให้ง่ายต่อการจัดการ เช่น

ไฟล์ partials/_header.erb

<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>Clean Blog</title>

  <!-- Bootstrap Core CSS -->
  <%= stylesheet_link_tag 'bootstrap.min' %>

  <!-- Custom CSS -->
  <%= stylesheet_link_tag 'clean-blog.min' %>

  <!-- Custom Fonts -->
  <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
  <link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
  <link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

  <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
  <![endif]-->

</head>

ไฟล์ partials/_navbar.erb

<!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header page-scroll">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="index.html">Start Bootstrap</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav navbar-right">
        <li>
          <a href="/">Home</a>
        </li>
        <li>
          <a href="about.html">About</a>
        </li>
        <li>
          <a href="post.html">Sample Post</a>
        </li>
        <li>
          <a href="contact.html">Contact</a>
        </li>
      </ul>
    </div>
    <!-- /.navbar-collapse -->
  </div>
  <!-- /.container -->
</nav>

ไฟล์ partials/_footer.erb

<!-- Footer -->
<footer>
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <ul class="list-inline text-center">
          <li>
            <a href="#">
              <span class="fa-stack fa-lg">
                <i class="fa fa-circle fa-stack-2x"></i>
                <i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
              </span>
            </a>
          </li>
          <li>
            <a href="#">
              <span class="fa-stack fa-lg">
                <i class="fa fa-circle fa-stack-2x"></i>
                <i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
              </span>
            </a>
          </li>
          <li>
            <a href="#">
              <span class="fa-stack fa-lg">
                <i class="fa fa-circle fa-stack-2x"></i>
                <i class="fa fa-github fa-stack-1x fa-inverse"></i>
              </span>
            </a>
          </li>
        </ul>
        <p class="copyright text-muted">Copyright &copy; Your Website 2014</p>
      </div>
    </div>
  </div>
</footer>

Index Page

ตอนนี้หน้า index.html.erb ก็จะมีการลิงค์ไปยัง Partials ชื่อว่า site_header.erb ดังนี้

---
pageable: true
per_page: 10
---

<%= partial "partials/site_header" %>

<div class="container">
  <div class="row">
    <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">

      <% page_articles.each_with_index do |article, i| %>

        <div class="post-preview">
            <h2 class="post-title"><%= link_to article.title, article %></h2>
            <h3 class="post-subtitle"><%= article.summary %></h3>
          <p classs="post-meta">Posted by Author on <%= article.date.strftime('%B %d, %Y') %></p>
        </div>
        <hr>

      <% end %>

    </div>
  </div>
</div>

<hr>

ไฟล์ partials/_site_header.erb

<!-- Page Header -->
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url('images/home-bg.jpg')">
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <div class="site-heading">
          <h1>Clean Blog</h1>
          <hr class="small">
          <span class="subheading">A Clean Blog Theme by Start Bootstrap</span>
        </div>
      </div>
    </div>
  </div>
</header>

Create Post Template

ต่อมาทำหน้า Template สำหรับ Single Post โดยสร้างไว้ที่ partials/post.erb ดังนี้

<%= partial "partials/post_header" %>

<article>
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <%= current_article.body %>
      </div>
    </div>
  </div>
</article>

โดยเราสามารถเข้าถึง content ของ Post ได้ด้วย current_article.body

และไฟล์ partials/_post_header.erb เป็นดังนี้

<!-- Page Header -->
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url('/images/post-bg.jpg')">
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <div class="post-heading">
          <h1>Man must explore, and this is exploration at its greatest</h1>
          <h2 class="subheading">Problems look mighty small from 150 miles up</h2>
          <span class="meta">Posted by <a href="#">Start Bootstrap</a> on August 24, 2014</span>
        </div>
      </div>
    </div>
  </div>
</header>

Config.rb

ต่อมาทำการแก้ไขไฟล์ config.rb นิดหน่อย โดยตั้งค่าให้เป็น Pretty URLs

activate :directory_indexes

แก้ไขหน้า layout.erb

ทำการแก้ไขหน้า layout.erb อีกครั้ง เพื่อเช็คว่า หากเป็นหน้า Single Post ให้แสดง Post Template หากเป็นหน้า index ก็ให้แสดงไฟล์ index.html.erb

<% unless is_blog_article? %>
  <%= yield %>
<% else %>
  <%= partial "partials/post" %>
<% end %>

สุดท้าย เพื่อเรามีบทความหลายๆบทความ การจะเซฟไว้ที่โฟลเดอร์ source มันจะทำให้ดูรก ก็เลยสร้างโฟลเดอร์ใหม่ ขึ้นมาโดยเฉพาะ เพื่อเอาไว้จัดเก็บบทความทั้งหมด ผมตั้งชื่อให้มันว่า source/posts

นำไฟล์บทความทั้งหมด ย้ายไปไว้ในโฟลเดอร์นี้ และแก้ไข config.rb โดยแก้จาก

blog.sources = "{year}-{month}-{day}-{title}.html"

เป็น

blog.sources = "/posts/{year}-{month}-{day}-{title}"

สำหรับไฟล์ Part 3 สามารถดูได้ที่นี

Source Code

Chai Chai Phonbopit : MEAN Stack @Nextzy • ผู้ชายธรรมดาๆ ที่ชื่นชอบ Android, JavaScript (Node.js) และ Open Source มีงานอดิเรกเป็น Acoustic Guitar และ Football

บทความล่าสุด