Devahoy Logo
PublishedAt

Ghost

สอนสร้าง Theme Ghost เพื่อไปขาย Themeforest ตอนที่ 2

สอนสร้าง Theme Ghost เพื่อไปขาย Themeforest ตอนที่ 2

มาต่อที่ Part 2 กันเลยครับหลักจาก Part 1 เราพูดถึง Ghost และการ Setup โปรเจ็คพื้นฐานได้แล้วนะครับ ตอนที่สิ่งที่ทุกคนเป็นก็คือ การติดตั้ง Ghost ลงบน localhost มีไฟล์ HTML Template ที่ดาวน์โหลดมาจาก StartBootstrap และพร้อมที่จะทำการ develop แล้ว

ต่อไปก็คือการแปลง Template Clean-Blog จาก HTML ให้เป็น Template ของ Ghost กัน ก่อนอื่น หากท่านเพิ่งมาอ่าน ขอบอกว่า บทความนี้เป็น Part 2 จากทั้งหมด 5 บทความ ในซีรีย์ สอนเขียน Ghost Theme เพื่อขายบน Themeforest นะครับ ติดตามอ่านได้จากรายชื่อข้างล่างเลย

Table of Contents

Create Index Page

เริ่มต้น ทำการก็อปปี้ไฟล์ index.html ใน Template Clean-Blog มาใส่ในไฟล์ index.hbs ของเราเลยครับ แบบนี้

1
<!doctype html>
2
<html lang="en">
3
<head>
4
<meta charset="utf-8" />
5
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
<meta name="viewport" content="width=device-width, initial-scale=1" />
7
<meta name="description" content="" />
8
<meta name="author" content="" />
9
10
<title>Clean Blog</title>
11
12
<!-- Bootstrap Core CSS -->
13
<link href="css/bootstrap.min.css" rel="stylesheet" />
14
15
<!-- Custom CSS -->
16
<link href="css/clean-blog.min.css" rel="stylesheet" />
17
18
<!-- Custom Fonts -->
19
<link
20
href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css"
21
rel="stylesheet"
22
type="text/css"
23
/>
24
<link
25
href="http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic"
26
rel="stylesheet"
27
type="text/css"
28
/>
29
<link
30
href="http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800"
31
rel="stylesheet"
32
type="text/css"
33
/>
34
35
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
36
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
37
<!--[if lt IE 9]>
38
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
39
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
40
<![endif]-->
41
</head>
42
43
<body>
44
<!-- Navigation -->
45
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
46
<div class="container-fluid">
47
<!-- Brand and toggle get grouped for better mobile display -->
48
<div class="navbar-header page-scroll">
49
<button
50
type="button"
51
class="navbar-toggle"
52
data-toggle="collapse"
53
data-target="#bs-example-navbar-collapse-1"
54
>
55
<span class="sr-only">Toggle navigation</span>
56
<span class="icon-bar"></span>
57
<span class="icon-bar"></span>
58
<span class="icon-bar"></span>
59
</button>
60
<a class="navbar-brand" href="index.html">Start Bootstrap</a>
61
</div>
62
63
<!-- Collect the nav links, forms, and other content for toggling -->
64
<div class="navbar-collapse collapse" id="bs-example-navbar-collapse-1">
65
<ul class="nav navbar-nav navbar-right">
66
<li>
67
<a href="index.html">Home</a>
68
</li>
69
<li>
70
<a href="about.html">About</a>
71
</li>
72
<li>
73
<a href="post.html">Sample Post</a>
74
</li>
75
<li>
76
<a href="contact.html">Contact</a>
77
</li>
78
</ul>
79
</div>
80
<!-- /.navbar-collapse -->
81
</div>
82
<!-- /.container -->
83
</nav>
84
85
<!-- Page Header -->
86
<!-- Set your background image for this header on the line below. -->
87
<header class="intro-header" style="background-image: url('img/home-bg.jpg')">
88
<div class="container">
89
<div class="row">
90
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
91
<div class="site-heading">
92
<h1>Clean Blog</h1>
93
<hr class="small" />
94
<span class="subheading">A Clean Blog Theme by Start Bootstrap</span>
95
</div>
96
</div>
97
</div>
98
</div>
99
</header>
100
101
<!-- Main Content -->
102
<div class="container">
103
<div class="row">
104
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
105
<div class="post-preview">
106
<a href="post.html">
107
<h2 class="post-title">Man must explore, and this is exploration at its greatest</h2>
108
<h3 class="post-subtitle">Problems look mighty small from 150 miles up</h3>
109
</a>
110
<p class="post-meta">Posted by <a href="#">Start Bootstrap</a> on September 24, 2014</p>
111
</div>
112
<hr />
113
<div class="post-preview">
114
<a href="post.html">
115
<h2 class="post-title">
116
I believe every human has a finite number of heartbeats. I don't intend to waste any
117
of mine.
118
</h2>
119
</a>
120
<p class="post-meta">Posted by <a href="#">Start Bootstrap</a> on September 18, 2014</p>
121
</div>
122
<hr />
123
<div class="post-preview">
124
<a href="post.html">
125
<h2 class="post-title">Science has not yet mastered prophecy</h2>
126
<h3 class="post-subtitle">
127
We predict too much for the next year and yet far too little for the next ten.
128
</h3>
129
</a>
130
<p class="post-meta">Posted by <a href="#">Start Bootstrap</a> on August 24, 2014</p>
131
</div>
132
<hr />
133
<div class="post-preview">
134
<a href="post.html">
135
<h2 class="post-title">Failure is not an option</h2>
136
<h3 class="post-subtitle">
137
Many say exploration is part of our destiny, but it’s actually our duty to future
138
generations.
139
</h3>
140
</a>
141
<p class="post-meta">Posted by <a href="#">Start Bootstrap</a> on July 8, 2014</p>
142
</div>
143
<hr />
144
<!-- Pager -->
145
<ul class="pager">
146
<li class="next">
147
<a href="#">Older Posts &rarr;</a>
148
</li>
149
</ul>
150
</div>
151
</div>
152
</div>
153
154
<hr />
155
156
<!-- Footer -->
157
<footer>
158
<div class="container">
159
<div class="row">
160
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
161
<ul class="list-inline text-center">
162
<li>
163
<a href="#">
164
<span class="fa-stack fa-lg">
165
<i class="fa fa-circle fa-stack-2x"></i>
166
<i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
167
</span>
168
</a>
169
</li>
170
<li>
171
<a href="#">
172
<span class="fa-stack fa-lg">
173
<i class="fa fa-circle fa-stack-2x"></i>
174
<i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
175
</span>
176
</a>
177
</li>
178
<li>
179
<a href="#">
180
<span class="fa-stack fa-lg">
181
<i class="fa fa-circle fa-stack-2x"></i>
182
<i class="fa fa-github fa-stack-1x fa-inverse"></i>
183
</span>
184
</a>
185
</li>
186
</ul>
187
<p class="copyright text-muted">Copyright &copy; Your Website 2014</p>
188
</div>
189
</div>
190
</div>
191
</footer>
192
193
<!-- jQuery -->
194
<script src="js/jquery.min.js"></script>
195
196
<!-- Bootstrap Core JavaScript -->
197
<script src="js/bootstrap.min.js"></script>
198
199
<!-- Custom Theme JavaScript -->
200
<script src="js/clean-blog.min.js"></script>
201
</body>
202
</html>

ด้านบน มันยังลิงค์ไปยังไฟล์ resource ของเราไม่ถูกต้องนะครับ เนื่องจากว่าเราเก็บไฟล์ assets ต่างๆ ไว้ในโฟลเดอร์ assets ฉะนั้นก็ทำการลิงค์ให้มันถูกต้องด้วยครับ จากโค๊ดด้านบน แก้พวก script ด้านล่างนี้ด้วย

1
<!-- Bootstrap Core CSS -->
2
<link href="assets/css/bootstrap.min.css" rel="stylesheet" />
3
4
<!-- Custom CSS -->
5
<link href="assets/css/clean-blog.min.css" rel="stylesheet" />
6
7
<header class="intro-header" style="background-image: url('assets/img/home-bg.jpg')">
8
<!-- jQuery -->
9
<script src="assets/js/jquery.min.js"></script>
10
11
<!-- Bootstrap Core JavaScript -->
12
<script src="assets/js/bootstrap.min.js"></script>
13
14
<!-- Custom Theme JavaScript -->
15
<script src="assets/js/clean-blog.min.js"></script>
16
</header>

จากนั้นลองเปิดหน้าเว็บเราใหม่ http://localhost:2368 ต้องได้เหมือน Template ดังภาพ

Index

ทีนี้จะเห็นว่าบทความ มันไม่ได้มาจากบทความที่เราเขียนเลย แต่เป็นบทความที่ใส่ไว้ในหน้า index เท่านั้น ฉะนั้นเราก็จะมาแก้ส่วนนี้กัน ให้มันดึงโพสจากฐานข้อมูลของเรามาแสดง

ลองสังเกตในไฟล์ index.hbs จะเห็นว่ามีส่วนที่เป็นการแสดงโพสอยู่ ก็คือ tag นี้

1
<div class='post-preview'>
2
<a href='post.html'>
3
<h2 class='post-title'>
4
Failure is not an option
5
</h2>
6
<h3 class='post-subtitle'>
7
Many say exploration is part of our destiny, but it’s actually our duty to future generations.
8
</h3>
9
</a>
10
<p class='post-meta'>Posted by <a href='#'>Start Bootstrap</a> on July 8, 2014</p>
11
</div>
12
<hr />

หนึ่งโพส จะมีครอบด้วย tag ด้านบน 1 ชุด แสดงถึง 1 โพส ฉะนั้น เราจะเปลี่ยนเป็นการใช้ Helper Class ของ Ghost เพื่อทำการวนลูปหาโพสทั้งหมด มาแสดงในหน้าแรก ก็จะได้ดังนี้

1
{{#foreach posts}}
2
<div class='post-preview'>
3
<a href='{{url}}'>
4
<h2 class='post-title'>{{title}}</h2>
5
<h3 class='post-subtitle'>{{excerpt character='80'}}</h3>
6
</a>
7
<p classs='post-meta'>Posted by {{author}} on {{date format='MMMM DD, YYYY'}}</p>
8
</div>
9
<hr />
10
{{/foreach}}
  • {{#foreach posts}} : หมายถึงการเริ่มวนลูป เพื่อหาจำนวนบทความทั้งหมดของเรา เหมือน the_loop() ใน Wordpress
  • {{url}} : เป็นการแสดง url ของโพส จะใช้ได้ต้องอยู่ภายใน Post Context ซึ่ง foreach posts ก็คือการเรียก Post มาที่ละ Post
  • {{title}} : แสดงชื่อ Title ของโพส เช่นเดียวกันกับ {{url}} คือต้องใช้ภายใน Post Context
  • {{excerpt character="80"}} : คือการใช้ excerpt เป็นการตัดบทความ โดยกำหนดไว้ว่า ให้มีจำนวนตัวอักษรทั้งหมด ไม่เกิน 80 ตัวอักษร
  • {{author}} : ก็เป็นการเรียก ใช้ Author ซึ่งปกติจะอยู่ในแต่ละ Post อยู่แล้ว ทำให้เราสามารถเรียกใช้เช่น {{author.name}} ชื่อผู้โพส - — {{author.bio}} : รายละเอียดคนโพส ส่วน {{author}} เฉยๆ มันคือ Helper ที่แสดงชื่อคนโพส และลิงค์ไปหน้า Author ให้เลย
  • {{date format="MMMM DD, YYYY"}} : เป็นการแสดงวันที่โพส โดยกำหนด format เป็น เดือน วันที่, ปี

เข้าไปเพิ่มบทความให้เว็บเราซักเล็กน้อย

Add Content

ต่อมาลองเปิดหน้าเว็บดูอีกครั้ง http://localhost:2368 จะเห็นโพสของเราแล้ว

Complete Index

หน้า Index ก็ถือว่าเป็นอันเรียบร้อย :D

Create Post & Page

ต่อมาสร้างหน้า Post เอาไว้สำหรับเข้าไปดูรายละเอียด ของแต่ละโพส ทำเหมือนกันกับ Index เลย คือไปก็อปหน้า post.html ของ Template Clean Blog มาไว้ในไฟล์ post.hbs ดังนี้

1
<!doctype html>
2
<html lang="en">
3
<head>
4
<meta charset="utf-8" />
5
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
<meta name="viewport" content="width=device-width, initial-scale=1" />
7
<meta name="description" content="" />
8
<meta name="author" content="" />
9
10
<title>Clean Blog - Sample Post</title>
11
12
<!-- Bootstrap Core CSS -->
13
<link href="css/bootstrap.min.css" rel="stylesheet" />
14
15
<!-- Custom CSS -->
16
<link href="css/clean-blog.min.css" rel="stylesheet" />
17
18
<!-- Custom Fonts -->
19
<link
20
href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css"
21
rel="stylesheet"
22
type="text/css"
23
/>
24
<link
25
href="http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic"
26
rel="stylesheet"
27
type="text/css"
28
/>
29
<link
30
href="http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800"
31
rel="stylesheet"
32
type="text/css"
33
/>
34
35
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
36
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
37
<!--[if lt IE 9]>
38
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
39
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
40
<![endif]-->
41
</head>
42
43
<body>
44
<!-- Navigation -->
45
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
46
<div class="container-fluid">
47
<!-- Brand and toggle get grouped for better mobile display -->
48
<div class="navbar-header page-scroll">
49
<button
50
type="button"
51
class="navbar-toggle"
52
data-toggle="collapse"
53
data-target="#bs-example-navbar-collapse-1"
54
>
55
<span class="sr-only">Toggle navigation</span>
56
<span class="icon-bar"></span>
57
<span class="icon-bar"></span>
58
<span class="icon-bar"></span>
59
</button>
60
<a class="navbar-brand" href="index.html">Start Bootstrap</a>
61
</div>
62
63
<!-- Collect the nav links, forms, and other content for toggling -->
64
<div class="navbar-collapse collapse" id="bs-example-navbar-collapse-1">
65
<ul class="nav navbar-nav navbar-right">
66
<li>
67
<a href="index.html">Home</a>
68
</li>
69
<li>
70
<a href="about.html">About</a>
71
</li>
72
<li>
73
<a href="post.html">Sample Post</a>
74
</li>
75
<li>
76
<a href="contact.html">Contact</a>
77
</li>
78
</ul>
79
</div>
80
<!-- /.navbar-collapse -->
81
</div>
82
<!-- /.container -->
83
</nav>
84
85
<!-- Page Header -->
86
<!-- Set your background image for this header on the line below. -->
87
<header class="intro-header" style="background-image: url('img/post-bg.jpg')">
88
<div class="container">
89
<div class="row">
90
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
91
<div class="post-heading">
92
<h1>Man must explore, and this is exploration at its greatest</h1>
93
<h2 class="subheading">Problems look mighty small from 150 miles up</h2>
94
<span class="meta">Posted by <a href="#">Start Bootstrap</a> on August 24, 2014</span>
95
</div>
96
</div>
97
</div>
98
</div>
99
</header>
100
101
<!-- Post Content -->
102
<article>
103
<div class="container">
104
<div class="row">
105
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
106
<p>
107
Never in all their history have men been able truly to conceive of the world as one: a
108
single sphere, a globe, having the qualities of a globe, a round earth in which all
109
the directions eventually meet, in which there is no center because every point, or
110
none, is center — an equal earth which all men occupy as equals. The airman's earth,
111
if free men make it, will be truly round: a globe in practice, not in theory.
112
</p>
113
114
<p>
115
Science cuts two ways, of course; its products can be used for both good and evil. But
116
there's no turning back from science. The early warnings about technological dangers
117
also come from science.
118
</p>
119
120
<p>
121
What was most significant about the lunar voyage was not that man set foot on the Moon
122
but that they set eye on the earth.
123
</p>
124
125
<p>
126
A Chinese tale tells of some men sent to harm a young girl who, upon seeing her
127
beauty, become her protectors rather than her violators. That's how I felt seeing the
128
Earth for the first time. I could not help but love and cherish her.
129
</p>
130
131
<p>
132
For those who have seen the Earth from space, and for the hundreds and perhaps
133
thousands more who will, the experience most certainly changes your perspective. The
134
things that we share in our world are far more valuable than those which divide us.
135
</p>
136
137
<h2 class="section-heading">The Final Frontier</h2>
138
139
<p>
140
There can be no thought of finishing for ‘aiming for the stars.’ Both figuratively and
141
literally, it is a task to occupy the generations. And no matter how much progress one
142
makes, there is always the thrill of just beginning.
143
</p>
144
145
<p>
146
There can be no thought of finishing for ‘aiming for the stars.’ Both figuratively and
147
literally, it is a task to occupy the generations. And no matter how much progress one
148
makes, there is always the thrill of just beginning.
149
</p>
150
151
<blockquote>
152
The dreams of yesterday are the hopes of today and the reality of tomorrow. Science
153
has not yet mastered prophecy. We predict too much for the next year and yet far too
154
little for the next ten.
155
</blockquote>
156
157
<p>
158
Spaceflights cannot be stopped. This is not the work of any one man or even a group of
159
men. It is a historical process which mankind is carrying out in accordance with the
160
natural laws of human development.
161
</p>
162
163
<h2 class="section-heading">Reaching for the Stars</h2>
164
165
<p>
166
As we got further and further away, it [the Earth] diminished in size. Finally it
167
shrank to the size of a marble, the most beautiful you can imagine. That beautiful,
168
warm, living object looked so fragile, so delicate, that if you touched it with a
169
finger it would crumble and fall apart. Seeing this has to change a man.
170
</p>
171
172
<a href="#">
173
<img class="img-responsive" src="img/post-sample-image.jpg" alt="" />
174
</a>
175
<span class="caption text-muted"
176
>To go places and do things that have never been done before – that’s what living is
177
all about.</span
178
>
179
180
<p>
181
Space, the final frontier. These are the voyages of the Starship Enterprise. Its
182
five-year mission: to explore strange new worlds, to seek out new life and new
183
civilizations, to boldly go where no man has gone before.
184
</p>
185
186
<p>
187
As I stand out here in the wonders of the unknown at Hadley, I sort of realize there’s
188
a fundamental truth to our nature, Man must explore, and this is exploration at its
189
greatest.
190
</p>
191
192
<p>
193
Placeholder text by
194
<a href="http://spaceipsum.com/">Space Ipsum</a>. Photographs by
195
<a href="https://www.flickr.com/photos/nasacommons/">NASA on The Commons</a>.
196
</p>
197
</div>
198
</div>
199
</div>
200
</article>
201
202
<hr />
203
204
<!-- Footer -->
205
<footer>
206
<div class="container">
207
<div class="row">
208
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
209
<ul class="list-inline text-center">
210
<li>
211
<a href="#">
212
<span class="fa-stack fa-lg">
213
<i class="fa fa-circle fa-stack-2x"></i>
214
<i class="fa fa-twitter fa-stack-1x fa-inverse"></i>
215
</span>
216
</a>
217
</li>
218
<li>
219
<a href="#">
220
<span class="fa-stack fa-lg">
221
<i class="fa fa-circle fa-stack-2x"></i>
222
<i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
223
</span>
224
</a>
225
</li>
226
<li>
227
<a href="#">
228
<span class="fa-stack fa-lg">
229
<i class="fa fa-circle fa-stack-2x"></i>
230
<i class="fa fa-github fa-stack-1x fa-inverse"></i>
231
</span>
232
</a>
233
</li>
234
</ul>
235
<p class="copyright text-muted">Copyright &copy; Your Website 2014</p>
236
</div>
237
</div>
238
</div>
239
</footer>
240
241
<!-- jQuery -->
242
<script src="js/jquery.min.js"></script>
243
244
<!-- Bootstrap Core JavaScript -->
245
<script src="js/bootstrap.min.js"></script>
246
247
<!-- Custom Theme JavaScript -->
248
<script src="js/clean-blog.min.js"></script>
249
</body>
250
</html>

จากนั้นก็แก้ไข path assets ให้ตรงเหมือนกันกับ Index (จะเห็นว่าโค๊ดเรายาว และมีหลายๆจุดที่โค๊ดเราซ้ำๆใช่มั้ยครับ หากมี 1-2ไฟล์ ก็ยังคงไม่ค่อยมีปัญหาเท่าไหร่ แต่หากลองคิดดู หากเรามี 10-20 หน้า ต้องมานั่งเปลี่ยน assets ก็อปโค๊ดยาวๆ คงไม่ดีแน่ นั่นแหละครับ จึงเกิดเป็นการใช้ default template และ partial ขึ้นมา เดียวใน Step ถัดไปจะมีการพูดถึงครับ

ทีนี้ลองเข้าหน้าเว็บ แล้วกดเข้าไปโพสไหนก็ได้ เพื่อจะดูว่าหน้า post.hbs มันเวิร์คหรือไม่ ??

จะเห็นหน้าเว็บมันเสีย ทำไมมันมองไม่เห็นไฟล์ css ทั้งที่เราเซทค่าแบบเดียวกันกับหน้า Index เมื่อลองดูโค๊ด จะเห็นว่ามันลิงค์ไปหน้านี้

1
http://localhost:2368/post-title/assets/css/clean-blog.min.css/

ซึ่งถ้าหาก อยู่หน้าแรก ไฟล์ css มันยังคงเรียกไปถูก แต่เมื่อไหร่ที่มันไปหน้า อื่น มันดันลิงค์ไปผิด path ทำให้หา Path ของ css จริงๆ ไม่เจอ วิธีแก้คือใช้ Assets Helper ครับ เปลี่ยนตรงแท็กทั้งหมดเป็นแบบนี้

1
<!-- Bootstrap Core CSS -->
2
<link href="{{asset "css/bootstrap.min.css"}}" rel="stylesheet">
3
4
<!-- Custom CSS -->
5
<link href="{{asset "css/clean-blog.min.css"}}" rel="stylesheet">
6
7
<header class="intro-header" style="background-image: url('{{asset "img/home-bg.jpg"}}')">
8
<!-- jQuery -->
9
<script src="{{asset "js/jquery.min.js"}}"></script>
10
11
<!-- Bootstrap Core JavaScript -->
12
<script src="{{asset "js/bootstrap.min.js"}}"></script>
13
14
<!-- Custom Theme JavaScript -->
15
<script src="{{asset "js/clean-blog.min.js"}}"></script>
  • {{asset "path/to/style.css"}} : คือ Asset Helper ซึ่งช่วยให้เราระบุ Relative Path ได้อย่างถูกต้อง โดยจะอ้างอิง relative กับโฟลเดอร์ assets ของเรา

ลองเข้าหน้าเว็บอีกรอบ คราวนี้ไม่มีปัญหาแล้ว

ต่อมา ในไฟล์ มีอะไรก็ไม่รู้เต็มไปหมดเลย ไม่ใช่โพสที่เราเขียนเองซักหน่อย เราจะแก้ไขโดยการแสดงเนื้อหาจริงๆ ของโพสนี้กัน ลองสังเกตว่า โพสจะอยู่ภายในแท็ก article และมี meta-post อยู่ในส่วน header แบบนี้

1
<header>{{meta-post}}</header>
2
<article>{{post}}</article>

ฉะนั้น เราก็ทำการเปลี่ยนแปลง โดยลบ header และ article ทั้งหมดทิ้ง แล้วใช้ Helper แทน ดังนี้

1
{{#post}}
2
<header class='intro-header' style="background-image: url('{{asset "img/home-bg.jpg"}}')">
3
<div class='container'>
4
<div class='row'>
5
<div class='col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1'>
6
<div class='post-heading'>
7
<h1>{{title}}</h1><h2 class='subheading'>{{excerpt words='20'}}</h2>
8
9
<span class='meta'>Posted by {{author}} on {{date format='MMMM DD, YYYY'}}</span>
10
<span class='meta'>{{tags separator=' | ' prefix='Tagged in:'}}</span>
11
12
</div>
13
</div>
14
</div>
15
</div>
16
</header>
17
18
<article>
19
<div class='container'>
20
<div class='row'>
21
<div class='col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1'>
22
{{content}}
23
</div>
24
</div>
25
</div>
26
</article>
27
28
<hr />
29
{{/post}}

จากโค๊ดด้านบน สิ่งที่ไม่เปลี่ยนคือ Header Background จะใช้รูปเดียวกันกับหน้า Home ส่วนนี้เดียวจะเอาไว้ปรับแต่งที่หลัง คือเราสามารถเลือกใช้ Image ของแต่ละโพสได้ (Post Image)

  • {{#post}} และ {{/post}} : หมายถึงการเรียกข้อมูลของ Post หากเราไม่ใส่ ค่าที่ได้จะเป็น undefined
  • {{title}} : แสดง Title ของโพส
  • {{excerpt words="20"}} : แสดง Excerpt ของโพส โดยจำกัดที่ 20 คำ
  • {{author}} : แสดงชื่อ Author และลิงค์ไปยังหน้า Author ด้วย
  • {{date format="MMMM DD, YYYY"}} : แสดงวันที่ ฟอแมตเดียวกันกับหน้า Index
  • {{tags separator=" | " prefix="Tagged in:"}} : คือการแสดง Tag โดยจะได้เป็น List รายชื่อของ Tag แต่ว่ามีออปชั่นเพิ่มขึ้นมา 2 อย่างคือ
    • separator : หมายถึง หากมีหลายๆ Tag เราจะใช้อะไรแบ่ง หรือขั้นระหว่าง Tag ในที่นี้ใช้ | (pipe)
    • prefix : หมายถึง คำขึ้นต้น ก่อนที่จะแสดง Tag List

เมื่อลองเข้าหน้า บทความ ไหนก็ได้ ก็จะสามารถเห็นเนื้อหาของบทความนั้นๆ ได้อย่างถูกต้อง ดังรูป

Post

โอเค ตอนนี้เราก็สามารถที่จะทำ Index และ Post ได้แล้ว แต่ยังมีโค๊ดหลายๆส่วนยังดูเยอะ และจัดการลำบากอยู่ ใน Part 3 เราจะมาพูดถึง Default Template และ Partial กันครับ เพื่อทำให้มันสะดวกขึ้น คอยติดตามในวันพรุ่งนี้นะครับ :D

Authors
avatar

Chai Phonbopit

เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust

Related Posts