Xây dựng một CMS: Cấu trúc và Giao diện
() translation by (you can also view the original English article)



Có một xu hướng về máy chủ web theo hướng "thiết kế CMS phẳng". Điều này đơn giản là chỉ đến một Hệ thống Quản lý Nội dung (CMS) mà không lưu trữ thông tin của nó trong cơ sở dữ liệu. Thay vào đó, tất cả thông tin được lưu trữ trong các tập tin văn bản thuần túy. Vì nhiều máy chủ riêng ảo (VPS) ngày nay đang sử dụng ổ đĩa cứng dựa trên RAM, cách tiếp cận này thì nhanh hơn và an toàn hơn một chút.
Trong loạt bài này, tôi sẽ hướng dẫn cho bạn cách tạo một CMS có hệ thống tập tin phẳng (Flat File System) sử dụng một số công nghệ web tiêu chuẩn. Những hệ thống này không đầy đủ tính năng như những hệ thống khác, nhưng có những tính năng cơ bản cùng với thời gian đáp ứng tốt.
Với tất cả các thông tin trên ổ đĩa cứng, việc tổ chức tập tin trở thành một vấn đề lớn. Với suy nghĩ đó, thông tin trang web sẽ nằm trong một thư mục khác so với thông tin về giao diện và bố cục. Đồng thời, mỗi loại trang có thư mục riêng của nó bên trong thư mục site với một thư mục parts cho các bộ phận nhỏ của CMS. Điều này giữ cho mọi thứ nằm trong vị trí riêng của nó và tạo ra một hệ thống linh hoạt.
Cấu trúc Thư mục Chính
Trong thư mục mà trong đó bạn sẽ xây dựng dự án, hãy tạo các thư mục sau đây: src, site, và themes. Thư mục src sẽ chứa code của máy chủ, thư mục site là dành cho tất cả thông tin của trang web, và thư mục themes cho bố cục và thông tin về theme.
Trong thư mục themes, bạn cần tạo một thư mục layouts và một styling. Thư mục layouts sẽ chứa các bố cục trang web khác nhau. Bằng cách tách biệt thông tin bố cục khỏi thông tin về giao diện, các theme trở nên linh hoạt hơn nhiều. Hiện tại, sẽ có một bố cục được gọi là SingleCol.
Để tạo ra toàn bộ giao diện và bố cục, tôi sử dụng Sass, Compass và Susy. Sass là một ngôn ngữ xử lý Stylesheet tùy biến. Nó đưa ra một cách làm thiết thực hơn để tạo các stylesheet CSS cho trang web của bạn. Compass là một extension (phần mở rộng) cho Sass. Sassy-buttons là một extension của Sass để tạo ra các nút bấm đẹp mắt trên trang web. Susy cũng là một extension để tạo ra một hệ thống Grid cho trang web của bạn.
Vì Ruby được cài đặt sẵn trên tất cả các máy Mac, nên bạn sẽ không cần cài đặt nó. Để cài đặt Ruby trên một hệ thống Windows, bạn sẽ cần phải tải về Windows Installer của Ruby. Trên Linux, bạn cần sử dụng trình quản lý gói (Package Manager) của hệ thống để cài đặt Ruby.
Một khi Ruby đã ở trong hệ thống của bạn, bạn có thể cài đặt Sass, Compass, Sassy-buttons và Susy bằng các lệnh sau:
1 |
gem install sass
|
2 |
gem install sassy-buttons
|
3 |
gem install compass
|
4 |
gem install susy
|
Đối với hướng dẫn này, tôi đang sử dụng Sass 3.4.16, Sassy-buttons 0.2.6, Compass 1.0.3 và Susy 2.2.5. Tùy thuộc vào cấu hình hệ thống của bạn, bạn có thể phải chạy các lệnh này với sudo
đằng trước chúng.
Bố cục
Để bắt đầu tạo các bố cục, hãy chạy các lệnh này trong thư mục SingleCol
:
1 |
compass init |
Điều này sẽ tạo ra thư mục sass và stylesheets, và một tập tin có tên là config.rb. Vì tôi thích sử dụng css cho thư mục stylesheet, nên hãy đổi tên thư mục stylesheets thành css. Ngoài ra, hãy tạo một thư mục js cho bất kỳ các tập tin JavaScript cần thiết nào cho bố cục. Mở tập tin config.rb và làm cho nó trông giống như cái này:
1 |
require 'susy' |
2 |
http_path = "/" |
3 |
css_dir = "css" |
4 |
sass_dir = "sass" |
5 |
images_dir = "images" |
6 |
javascripts_dir = "js" |
Bây giờ, để tạo bố cục cơ bản của trang web, hãy tạo một tập tin trong thư mục layout đặt tên là template.html. Bên trong tập tin này, hãy thêm code sau:
1 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2 |
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> |
3 |
<head>
|
4 |
<meta name="generator" content="goPress Servery by Custom Computer Tools."> |
5 |
<meta charset="utf-8"> |
6 |
<title>
|
7 |
{{{title}}} |
8 |
</title>
|
9 |
<link rel="stylesheet" type="text/css" href="{{{WebAddress}}}/stylesheets.css"> |
10 |
{{{head}}} |
11 |
</head>
|
12 |
|
13 |
<body>
|
14 |
<div id='wrap'> |
15 |
<div id='headerwrap'> |
16 |
<div id='header'> |
17 |
{{{header}}} |
18 |
</div>
|
19 |
<div id='navigation'> |
20 |
{{{navbar}}} |
21 |
</div>
|
22 |
</div>
|
23 |
<div id='sidebar'> |
24 |
{{{sidebar}}} |
25 |
</div>
|
26 |
<div id='content'> |
27 |
{{{content}}} |
28 |
</div>
|
29 |
<div id='footer'> |
30 |
{{{footer}}} |
31 |
</div>
|
32 |
</div>
|
33 |
<script type="text/javascript" src="{{{WebAddress}}}/scripts.js"></script> |
34 |
</body>
|
35 |
|
36 |
</html>
|
Template này tạo ra một trang tiêu chuẩn cho trang web. Mỗi trang có một header với thanh điều hướng, một sidebar, một khu vực nội dung, và một khu vực footer. Thứ cuối cùng được nạp là các javascript cần thiết cho trang web.
Mỗi phần được đại diện bằng một macro Handlebar. Máy chủ khai triển các macro trước khi đưa nó đến với người dùng.
Trong thư mục sass, hãy tạo một tập tin có tên là base.scss và đặt code này vào:
1 |
@import 'compass/reset'; |
2 |
@import 'susy'; |
3 |
|
4 |
$susy: ( |
5 |
flow: ltr, |
6 |
math: fluid, |
7 |
output: float, |
8 |
gutter-position: after, |
9 |
container: auto, |
10 |
container-position: center, |
11 |
columns: 16, |
12 |
gutters: .25, |
13 |
column-width: false, |
14 |
global-box-sizing: content-box, |
15 |
last-flow: to, |
16 |
debug: ( |
17 |
image: hide, |
18 |
color: rgba(#66f, .25), |
19 |
output: background, |
20 |
toggle: top right, |
21 |
),
|
22 |
use-custom: ( |
23 |
background-image: true, |
24 |
background-options: false, |
25 |
box-sizing: true, |
26 |
clearfix: false, |
27 |
rem: true, |
28 |
)
|
29 |
);
|
30 |
|
31 |
body { |
32 |
}
|
33 |
|
34 |
#wrap { |
35 |
@include container(16); |
36 |
width: 1024px; |
37 |
display: block; |
38 |
}
|
39 |
|
40 |
#headerwrap { |
41 |
@include span(16 of 16); |
42 |
margin-bottom: 20px; |
43 |
}
|
44 |
|
45 |
#header { |
46 |
margin-top: 20px; |
47 |
margin-left: auto; |
48 |
margin-right: auto; |
49 |
width: 95%; |
50 |
}
|
51 |
|
52 |
#content { |
53 |
@include span(11 of 16); |
54 |
}
|
55 |
|
56 |
.col1 { |
57 |
@include span(5 of 10); |
58 |
}
|
59 |
|
60 |
.col2 { |
61 |
@include span(last 5 of 10); |
62 |
}
|
63 |
|
64 |
#footer .col2 { |
65 |
width: auto; |
66 |
}
|
67 |
|
68 |
.box { |
69 |
@include span(4 of 10); |
70 |
}
|
71 |
|
72 |
#sidebar { |
73 |
@include span(last 4 of 16); |
74 |
}
|
75 |
|
76 |
#footer { |
77 |
@include span(16 of 16); |
78 |
}
|
79 |
|
80 |
/** CSS dropdown menu **/
|
81 |
|
82 |
#navigation { |
83 |
margin-top: 20px; |
84 |
margin-left: auto; |
85 |
margin-right: auto; |
86 |
width: 95%; |
87 |
}
|
88 |
|
89 |
#menuh-container { |
90 |
top: 1em; |
91 |
left: 1em; |
92 |
display: inline; |
93 |
width: 100%; |
94 |
}
|
95 |
|
96 |
#menuh { |
97 |
margin-top: 1em; |
98 |
display: inline; |
99 |
width: 100%; |
100 |
}
|
101 |
|
102 |
#menuh ul li { |
103 |
display: inline-block; |
104 |
width: fit-content; |
105 |
}
|
106 |
|
107 |
#menuh a |
108 |
{
|
109 |
text-align: center; |
110 |
display:block; |
111 |
white-space:nowrap; |
112 |
margin:0; |
113 |
padding: 5px; |
114 |
text-decoration: none; |
115 |
}
|
116 |
|
117 |
#menuh ul |
118 |
{
|
119 |
list-style:none; |
120 |
margin: 0px 20px 0px 20px; |
121 |
padding: 0px; |
122 |
}
|
123 |
|
124 |
#menuh li |
125 |
{
|
126 |
position:relative; |
127 |
min-height: 1px; |
128 |
vertical-align: bottom; |
129 |
width: fit-content; |
130 |
}
|
131 |
|
132 |
#menuh ul ul |
133 |
{
|
134 |
position: absolute; |
135 |
z-index: 500; |
136 |
top: 50px; |
137 |
left: 20px; |
138 |
display: none; |
139 |
padding: 0.5em; |
140 |
margin: -1em 0 0 -1em; |
141 |
}
|
142 |
|
143 |
#menuh ul ul li { |
144 |
width: 100%; |
145 |
}
|
146 |
|
147 |
#menuh ul ul li a { |
148 |
text-align: left; |
149 |
}
|
150 |
|
151 |
#menuh ul ul ul |
152 |
{
|
153 |
left: 90px; |
154 |
}
|
155 |
|
156 |
div#menuh li:hover |
157 |
{
|
158 |
cursor:pointer; |
159 |
z-index:100; |
160 |
}
|
161 |
|
162 |
div#menuh li:hover ul ul, |
163 |
div#menuh li li:hover ul ul, |
164 |
div#menuh li li li:hover ul ul, |
165 |
div#menuh li li li li:hover ul ul |
166 |
{display:none;} |
167 |
|
168 |
div#menuh li:hover ul, |
169 |
div#menuh li li:hover ul, |
170 |
div#menuh li li li:hover ul, |
171 |
div#menuh li li li li:hover ul |
172 |
{display:block;} |
173 |
|
174 |
/* End CSS Drop Down Menu */
|
Code sass này nạp trong các phong cách reset của compass để vô hiệu hoá các phong cách mặc định của trình duyệt. Sau đó, nó nạp và thiết lập susy để tạo ra bố cục grid thích hợp cho tất cả các phần tử của trang web.
css cho hệ thống điều hướng là ở phía sau các định nghĩa trang. Các menu thả xuống ẩn sẽ hiện ra khi di chuyển chuột lên trên. Điều này tạo ra một hệ thống menu chỉ bằng css.
Tất cả những phong cách này giúp định nghĩa cấu trúc cơ bản của trang web. Không có phong cách nào tạo ra giao diện cho trang web, chỉ xác định vị trí của nó. Tất cả các phong cách trang trí được xử lý bởi nội dung trong thư mục styling.
Giao diện
Trong thư mục styling, hãy tạo một thư mục có tên là Basic. Khởi tạo thông tin sass như đã làm đối với thư mục layouts/SingleCol. Trong thư mục này, hãy chạy lệnh sau:
1 |
compass init |
Việc này sẽ tạo ra thư mục sass và stylesheets, và một tập tin có tên là config.rb. Vì tôi thích sử dụng css cho thư mục stylesheet, nên hãy đổi tên thư mục stylesheets thành css. Đồng thời, tạo một thư mục js cho bất kỳ JavaScript nào để tạo theme. Mở tập tin config.rb và làm cho nó giống như cái sau đây:
1 |
require 'sassy-buttons' |
2 |
http_path = "/" |
3 |
css_dir = "css" |
4 |
sass_dir = "sass" |
5 |
images_dir = "images" |
6 |
javascripts_dir = "js" |
Để trang trí các nút bấm ở trên trang web, tôi thích sử dụng sassy-buttons. Do đó, nó là yêu cầu trước tiên, và sau đó là cấu trúc thư mục.
Trong thư mục Basic/sass, tạo tập tin Basic.scss với thông tin sau:
1 |
// Welcome to Compass. |
2 |
// In this file you should write your main styles. (or centralize your imports) |
3 |
// Import this file using the following HTML or equivalent: |
4 |
// <link href='/stylesheets/screen.css' media='screen, projection' rel='stylesheet' type='text/css' /> |
5 |
//
|
6 |
@import 'compass/css3'; |
7 |
@import 'sassy-buttons'; |
8 |
|
9 |
$style-color1: rgb(247, 237, 222); |
10 |
$style-color2: #ffedd1; |
11 |
$style-color3: rgb(245, 213, 166); |
12 |
$style-color4: #f0d5ad; |
13 |
|
14 |
//
|
15 |
// Clear Fix |
16 |
//
|
17 |
.clearfix:after { |
18 |
content: '.'; |
19 |
display: block; |
20 |
clear: both; |
21 |
visibility: hidden; |
22 |
line-height: 0; |
23 |
height: 0; |
24 |
}
|
25 |
|
26 |
.clearfix { |
27 |
display: inline-block; |
28 |
}
|
29 |
|
30 |
html[xmlns] .clearfix { |
31 |
display: block; |
32 |
}
|
33 |
|
34 |
* html .clearfix { |
35 |
height: 1%; |
36 |
}
|
37 |
|
38 |
//
|
39 |
// Main Styling for Wood. |
40 |
//
|
41 |
@mixin standardsize { |
42 |
padding-top: 10px; |
43 |
padding-left: 15px; |
44 |
font-size: 19px; |
45 |
line-height: 1.25em; |
46 |
}
|
47 |
|
48 |
body { |
49 |
background-color: $style-color2; |
50 |
|
51 |
input[type='button'] { |
52 |
@include sassy-button('shiny', 10px, 16px, $style-color1, darken($style-color1, 20%), #000, bold); |
53 |
}
|
54 |
|
55 |
.button { |
56 |
@include sassy-button('shiny', 10px, 16px, $style-color1, darken($style-color1, 20%), #000, bold); |
57 |
display: inherit; |
58 |
margin-left: auto; |
59 |
margin-right: auto; |
60 |
margin-top: 10px; |
61 |
margin-bottom: 10px; |
62 |
text-align: center; |
63 |
}
|
64 |
|
65 |
#wrap { |
66 |
background-color: $style-color1; |
67 |
@include border-radius(.6em, .6em); |
68 |
margin-top: 10px; |
69 |
margin-bottom: 10px; |
70 |
border: 4px solid $style-color4; |
71 |
|
72 |
#header { |
73 |
background-color: $style-color2; |
74 |
@include border-radius(15px); |
75 |
background-repeat: no-repeat; |
76 |
border: 2px solid $style-color3; |
77 |
height: 130px; |
78 |
text-align: left; |
79 |
margin-top: 20px; |
80 |
font-size: 3em; |
81 |
|
82 |
h1 { |
83 |
a:link, a:visited { |
84 |
color: #000; |
85 |
text-decoration: none; |
86 |
}
|
87 |
padding-top: 40px; |
88 |
padding-left: 20px; |
89 |
}
|
90 |
h6 { |
91 |
font-size: .4em; |
92 |
font-style: italic; |
93 |
padding-left: 20px; |
94 |
}
|
95 |
}
|
96 |
#sidebar { |
97 |
background-color: $style-color2; |
98 |
@include border-radius(.6em, .6em); |
99 |
padding: .6em; |
100 |
vertical-align: text-top; |
101 |
overflow: hidden; |
102 |
margin-right: .5em; |
103 |
border: 2px solid $style-color3; |
104 |
hr { |
105 |
color: $style-color2; |
106 |
background-color: $style-color2; |
107 |
}
|
108 |
p, ul, li { |
109 |
@include standardsize; |
110 |
}
|
111 |
ul li { |
112 |
list-style-type: disc; |
113 |
margin-left: 25px; |
114 |
padding: 0; |
115 |
border: 0; |
116 |
outline: 0; |
117 |
font-size: 100%; |
118 |
vertical-align: baseline; |
119 |
background: transparent; |
120 |
}
|
121 |
li { |
122 |
margin-bottom: 10px; |
123 |
}
|
124 |
h1, h2, h3, h4, h5, h6 { |
125 |
@include standardsize; |
126 |
font-weight: bold; |
127 |
margin-top: .25em; |
128 |
margin-bottom: .25em; |
129 |
}
|
130 |
h1 { |
131 |
font-size: 2.5em; |
132 |
}
|
133 |
h2 { |
134 |
font-size: 2em; |
135 |
}
|
136 |
h3 { |
137 |
font-size: 1.5em; |
138 |
}
|
139 |
h4 { |
140 |
font-size: 1em; |
141 |
}
|
142 |
h5 { |
143 |
font-size: .8em; |
144 |
}
|
145 |
h6 { |
146 |
font-size: .6em; |
147 |
}
|
148 |
input[type='button'] { |
149 |
margin-left: 120px; |
150 |
clear: both; |
151 |
}
|
152 |
}
|
153 |
#content { |
154 |
input[type='button'] { |
155 |
margin-left: 200px; |
156 |
clear: both; |
157 |
}
|
158 |
h1, h2, h3, h4, h5, h6 { |
159 |
@include standardsize; |
160 |
font-weight: bold; |
161 |
margin-top: .25em; |
162 |
margin-bottom: .25em; |
163 |
}
|
164 |
h1 { |
165 |
font-size: 2.5em; |
166 |
}
|
167 |
h2 { |
168 |
font-size: 2em; |
169 |
}
|
170 |
h3 { |
171 |
font-size: 1.5em; |
172 |
}
|
173 |
h4 { |
174 |
font-size: 1em; |
175 |
}
|
176 |
h5 { |
177 |
font-size: .8em; |
178 |
}
|
179 |
h6 { |
180 |
font-size: .6em; |
181 |
}
|
182 |
hr { |
183 |
margin-top: 30px; |
184 |
margin-bottom: 30px; |
185 |
}
|
186 |
p, ul, li, details, summary, pre { |
187 |
@include standardsize; |
188 |
}
|
189 |
details { |
190 |
p, pre { |
191 |
margin-left: 25px; |
192 |
}
|
193 |
}
|
194 |
ul li { |
195 |
list-style-type: disc; |
196 |
margin-left: 25px; |
197 |
padding: 0; |
198 |
border: 0; |
199 |
outline: 0; |
200 |
font-size: 100%; |
201 |
vertical-align: baseline; |
202 |
background: transparent; |
203 |
}
|
204 |
li { |
205 |
margin-bottom: 10px; |
206 |
}
|
207 |
.box { |
208 |
clear: both; |
209 |
background-color: $style-color4; |
210 |
float: none; |
211 |
margin-left: auto; |
212 |
margin-right: auto; |
213 |
margin-top: 1.0em; |
214 |
margin-bottom: 1em; |
215 |
@include border-radius(.6em, .6em); |
216 |
display: block; |
217 |
padding: .5em; |
218 |
}
|
219 |
img { |
220 |
@include border-radius(10px); |
221 |
margin: 20px auto 20px auto; |
222 |
}
|
223 |
}
|
224 |
#footer { |
225 |
border-top: 5px; |
226 |
border-style: solid; |
227 |
border-color: $style-color3; |
228 |
@include border-radius(.6em, .6em); |
229 |
margin-top: 30px; |
230 |
p { |
231 |
margin-bottom: .6em; |
232 |
@include standardsize; |
233 |
margin-right: 15px; |
234 |
}
|
235 |
}
|
236 |
}
|
237 |
}
|
238 |
|
239 |
// CSS dropdown menu |
240 |
#navigation { |
241 |
text-align: left; |
242 |
border: 2px solid $style-color3; |
243 |
background-color: $style-color2; |
244 |
@include border-radius(15px); |
245 |
}
|
246 |
|
247 |
#menuh { |
248 |
font-size: 1.3em; |
249 |
font-family: arial, helvetica, sans-serif; |
250 |
background-color: $style-color1; |
251 |
}
|
252 |
|
253 |
#menuh ul { |
254 |
background-color: $style-color2; |
255 |
}
|
256 |
|
257 |
#menuh ul ul { |
258 |
background-color: $style-color2; |
259 |
@include border-radius(15px); |
260 |
border: 2px solid $style-color3; |
261 |
}
|
262 |
|
263 |
#menuh a { |
264 |
background-color: $style-color2; |
265 |
color: #000; |
266 |
}
|
267 |
|
268 |
#menuh a:link, #menuh a:visited, #menuh a:active { |
269 |
color: #000; |
270 |
background-color: $style-color2; |
271 |
}
|
272 |
|
273 |
#menuh a:hover { |
274 |
color: #000; |
275 |
background-color: $style-color4; |
276 |
@include border-radius(5px); |
277 |
}
|
278 |
|
279 |
// End CSS Drop Down Menu |
280 |
// Misc classes |
281 |
.picture { |
282 |
border: 3px solid $style-color3; |
283 |
@include border-radius(8px); |
284 |
float: left; |
285 |
margin: 5px 15px 15px 15px; |
286 |
}
|
287 |
|
288 |
a:link, a:visited { |
289 |
color: darken($style-color1, 50); |
290 |
text-decoration: none; |
291 |
}
|
292 |
|
293 |
strong { |
294 |
font-weight: bold; |
295 |
}
|
296 |
|
297 |
table { |
298 |
margin: 20px; |
299 |
border: 3px solid; |
300 |
@include border-radius(10px); |
301 |
border-color: lighten($style-color2, 6); |
302 |
th { |
303 |
text-align: center; |
304 |
font-weight: bold; |
305 |
padding: 10px 0 10px 0; |
306 |
}
|
307 |
tbody { |
308 |
td { |
309 |
padding: 10px; |
310 |
}
|
311 |
tr:nth-child(2n+1) { |
312 |
background-color: darken($style-color2, 5); |
313 |
}
|
314 |
tr:nth-child(even) { |
315 |
background-color: lighten($style-color2, 2.5); |
316 |
}
|
317 |
}
|
318 |
}
|
319 |
|
320 |
#commentSpacer { |
321 |
width: 100%; |
322 |
margin-top: 20px; |
323 |
margin-left: 15px; |
324 |
}
|
325 |
|
326 |
.tutorial_excerpt { |
327 |
margin-left: 20px; |
328 |
}
|
329 |
|
330 |
.tutorial_thumbnail { |
331 |
float: left; |
332 |
margin-right: 20px; |
333 |
margin-left: 20px; |
334 |
margin-bottom: 20px; |
335 |
}
|
336 |
|
337 |
.tutorial_wrap { |
338 |
margin-bottom: 50px; |
339 |
float: left; |
340 |
}
|
341 |
|
342 |
img.wp-post-image { |
343 |
-moz-border-radius: 15px; |
344 |
border-radius: 15px; |
345 |
box-shadow: 10px 10px 5px gray; |
346 |
}
|
347 |
|
348 |
.showcode { |
349 |
margin: 20px auto 20px 30px; |
350 |
-moz-border-radius: 15px; |
351 |
border-radius: 15px; |
352 |
border: $style-color4 3px; |
353 |
border-style: solid; |
354 |
background: white; |
355 |
}
|
356 |
|
357 |
#socialmedia { |
358 |
width: 700px; |
359 |
margin-top: 20px; |
360 |
margin-left: 15px; |
361 |
}
|
362 |
|
363 |
#socialbuttons { |
364 |
margin: auto; |
365 |
}
|
366 |
|
367 |
#socialbuttons a { |
368 |
opacity: 0.8; |
369 |
filter: alpha(opacity = 80); |
370 |
-webkit-transition: all ease-in-out 0.2s; |
371 |
-moz-transition: all ease-in-out 0.2s; |
372 |
-ms-transition: all ease-in-out 0.2s; |
373 |
-o-transition: all ease-in-out 0.2s; |
374 |
transition: all ease-in-out 0.2s; |
375 |
}
|
376 |
|
377 |
#socialbuttons a:hover { |
378 |
opacity: 1; |
379 |
filter: alpha(opacity = 100); |
380 |
}
|
381 |
|
382 |
#socialbuttons a { |
383 |
display: inline-block; |
384 |
height: 28px; |
385 |
width: 30px; |
386 |
background-image: url(/images/ico-subscribe-social.png); |
387 |
background-repeat: no-repeat; |
388 |
}
|
389 |
|
390 |
#socialbuttons a.twitter { |
391 |
background-position: -30px 0; |
392 |
}
|
393 |
|
394 |
#socialbuttons a.facebook { |
395 |
background-position: -60px 0; |
396 |
}
|
397 |
|
398 |
#socialbuttons a.googleplus { |
399 |
background-position: -210px 0; |
400 |
}
|
401 |
|
402 |
dl { |
403 |
margin-left: 20px; |
404 |
margin-top: 20px; |
405 |
margin-bottom: 20px; |
406 |
font-size: 19px; |
407 |
line-height: 1.25em; |
408 |
}
|
409 |
|
410 |
dt { |
411 |
margin-left: 20px; |
412 |
margin-bottom: 20px; |
413 |
font-weight: bold; |
414 |
}
|
415 |
|
416 |
dd { |
417 |
margin-left: 40px; |
418 |
margin-bottom: 20px; |
419 |
}
|
Code này định nghĩa cách trang web sẽ hiển thị. Nó định nghĩa nền, màu sắc, phông chữ, vân vân... để tạo nên giao diện cho một trang web điển hình.
Thư mục styling/Basic chứa các tập tin cần thiết cho giao diện mặc định của trang 404, header, footer và sidebar của trang web. Do đó, hãy tạo tập tin 404.html và thêm code này vào:
1 |
<h2>404 Page</h2> |
2 |
|
3 |
<p>Sorry, we could not find the page.</p> |
Đây là trang lỗi 404 cơ bản. Bạn phải cẩn thận với thông tin được đưa ra ở đây, vì bạn không muốn tiết lộ quá nhiều thông tin về cách trang web của bạn hoạt động. Vì điều này sẽ được đặt trong khu vực nội dung của trang, nên nó sẽ dễ dàng để cho người dùng điều hướng khỏi nó.
Tiếp theo, tạo tập tin header.html với nội dung này:
1 |
<h1><a href='/'>Test Site</a></h1> |
2 |
<h6>A New Approach</h6> |
3 |
<br>
|
Đây chỉ là một header sườn mà không có mô tả, nhưng nó cho CMS một cái gì đó để hiển thị.
Tiếp theo, hãy tạo tập tin footer.html có nội dung sau:
1 |
<footer>
|
2 |
[Column1] |
3 |
<p>Copyrighted 2012 by <a href="{{{WebAddress}}}/">Your Company</a> |
4 |
[/Column1] |
5 |
[Column2] |
6 |
<p>Running on a flat CMS server!</p> |
7 |
[/Column2] |
8 |
</footer>
|
Tiếp theo, tạo tập tin sidebar.html có nội dung sau:
1 |
<h3>A Sidebar</h3> |
2 |
<p>This is a basic sidebar that can have other times.</p> |
Một lần nữa, đây là những phần giữ chỗ. Tất cả các tập tin này được sao chép vào thư mục site/parts và thay đổi theo nhu cầu của trang web. Những cái này là ở đây để cho máy chủ có thứ gì đó cùng với tên của chúng để sử dụng trên máy chủ trong trường hợp người dùng quên để tạo ra chúng.
Cấu trúc của Trang web
Với theme và bố cục đã được định nghĩa, đã đến lúc tạo ra nội dung và cấu trúc cơ bản cho trang web thật sự. Trong thư mục site, tạo các thư mục parts, pages, posts, images, css, js.
Parts
Thư mục parts sẽ chứa các đoạn code nhỏ của html/css/javascript sẽ tạo ra một đơn vị duy nhất được đặt ở nhiều vị trí của trang web. Các bộ phận này được tải lên máy chủ và kết hợp với nội dung của trang khi cần. Đối với trang demo của chúng ta, hãy tạo ra các bộ phận sau:
- footer.html với code sau:
1 |
<footer>
|
2 |
<p style="float: left;">Copyrighted 2012 by <a href="{{{WebAddress}}}/">Your Company</a> |
3 |
<p style="float: right;">Running on a flat CMS server!</p> |
4 |
</footer>
|
5 |
<script type="text/javascript"> |
6 |
window.PageName = "{{{PageName}}}"; |
7 |
</script>
|
- head.html với code sau:
1 |
<link rel="shortcut icon" href="{{{WebAddress}}}/images/favicon.ico" /> |
- header.html với code sau:
1 |
<h1><a href='{{{ServerAddress}}}/'>Test Site</a></h1> |
2 |
<h6>Flat File System CMS</h6> |
- navbar.html với code sau:
1 |
<div id="menuh-container"> |
2 |
<div id="menuh"> |
3 |
<ul>
|
4 |
<li>
|
5 |
<a class="top_parent">Pages</a> |
6 |
<ul>
|
7 |
<li>
|
8 |
<a href="{{{WebAddress}}}/flatcms">Flat CMS</a> |
9 |
</li>
|
10 |
</ul>
|
11 |
</li>
|
12 |
<li>
|
13 |
<a href="{{{WebAddress}}}/posts/blogs/flatcms">Blog</a> |
14 |
</li>
|
15 |
<li>
|
16 |
<a href="{{{WebAddress}}}/posts/news/flatcms" class="top_parent">News</a> |
17 |
</li>
|
18 |
<li>
|
19 |
<a href="{{{WebAddress}}}/about" class="top_parent">About</a> |
20 |
</li>
|
21 |
</ul>
|
22 |
</div>
|
23 |
</div>
|
- sidebar.html với code sau:
1 |
<h2>Side Bar</h2> |
2 |
<hr>
|
- socialmedia.html với code sau:
1 |
<div id="socialmedia"> |
2 |
<div id="socialbuttons"> |
3 |
<a href="" class="twitter" title="Twitter"></a> |
4 |
|
5 |
<a href="" class="googleplus" title="Google+"></a> |
6 |
</div>
|
7 |
<div id="commentSpacer" class="clearfix"></div> |
8 |
<!-- Put other Social Media items here (ie: Disqus, etc.); -->
|
9 |
</div>
|
Máy chủ nạp các bộ phận này bằng tên mà không cần phần mở rộng trong template Handlebar để khai triển. Ví dụ, bất cứ chỗ nào mà bộ phận socialmedia.html cần phải được đặt, thì bạn đặt macro {{socialmedia}}}
ở đó. Đồng thời, những bộ phận này có thể là HTML, Markdown hoặc bất kỳ định dạng nào khác mà máy chủ có thể xử lý. Trong các máy chủ mà tôi sẽ tạo ra, các loại tập tin được hỗ trợ là HTML, Jade/Amber, và Markdown. Tôi sẽ đi vào những chi tiết này trong hướng dẫn tạo máy chủ thật sự.
Pages
Tất cả các trang cho trang web sẽ được đặt trong thư mục pages. Còn bây giờ, hãy tạo các tập tin sau cùng với nội dung của chúng:
- main.html với code sau:
1 |
<h3>Flat CMS Test Site</h3> |
2 |
<p>This is the Main page of the test site.</p> |
- flatcms.md với code sau:
1 |
### Flat CMS Server |
2 |
|
3 |
This is a page about the flat CMS server. |
- about.md với code sau:
1 |
### About |
2 |
|
3 |
This would be a standard about page. |
Đây là các trang demo cho trang web. Tập tin bắt buộc duy nhất là main.html vì máy chủ sẽ nạp nội dung trang này vào bộ nhớ và phục vụ từ bộ nhớ. Những điều đó giúp tăng tốc độ tải front-page của trang web. Hai trang khác có phần mở rộng md vì chúng ở trong định dạng Markdown. Máy chủ sẽ dịch nội dung sang HTML trước khi nhúng vào bố cục của trang web.
Nhìn chung, các trang chứa thông tin không thay đổi nhiều theo thời gian. Chúng cung cấp cho người xem thông tin về trang web, mục đích và mục tiêu của nó.
Các trang có thể phân cấp một cách tự nhiên bằng cách tạo thư mục và các thư mục con cùng với các trang. Những cái tên thư mục này tạo ra các địa chỉ đến thư mục của các trang này.
Posts
Không giống pages, posts chứa các phần tử được cập nhật thường xuyên, ví dụ như, các bài viết và các tin tức hàng ngày/hàng tuần/hàng tháng. Khu vực này được dự kiến sẽ thay đổi thường xuyên. Trong thư mục posts, hãy tạo ra hai thư mục mới: blogs và news. Trong mỗi thư mục này, hãy tạo một thư mục flatcms. Những thư mục này sẽ chứa các bài viết và các tin tức cho trang web Flat CMS.
Trong thư mục posts/blogs/flatcms, hãy tạo các tập tin sau:
- index.amber với những nội dung sau:
1 |
h3 Flat CMS Blog |
2 |
|
3 |
p This is a rambling blog about a flat CMS. |
4 |
|
5 |
mixin article($title, $link, $excerpt, $date) |
6 |
div.entry |
7 |
div.tutorial_wrap |
8 |
div.tutorial_div |
9 |
a[href=$link] |
10 |
h3 #{$title} |
11 |
h5 #{$date} |
12 |
p.tutorial_excerpt #{$excerpt} |
13 |
div.clear |
14 |
|
15 |
+article("Flat CMS Running", "/posts/blogs/flatcms/flatcms", "Flat CMS Test Server is Running!", "August 12, 2015") |
- flatcms.md với những nội dung sau:
1 |
The New Server is Running |
2 |
---- |
3 |
|
4 |
After much work and programming, the flat CMS server is running. Stay tuned for more news! |
5 |
|
6 |
{{{socialmedia}}} |
index.amber là một template Jade để định nghĩa các bài viết khác nhau trong blog. Hệ thống template HTML Jade giúp dễ dàng thêm nội dung mới với một định dạng chuẩn xác. Các tham số cho macro tạo nên các phần tử khác nhau. Bạn có thể tìm hiểu thêm về Jade trên Tuts+.
Ở đây, phần mở rộng được sử dụng là amber vì ngôn ngữ Go tương ứng của Jade là Amber. Vì đó là nơi tôi bắt đầu, nên đó là cách tôi đã thực hiện nó. Nếu bạn muốn thay đổi phần mở rộng, đồng thời hãy nhớ thay đổi nó trong code cho máy chủ thích hợp.
Trong thư mục posts/news/flatcms, hãy tạo các tập tin sau:
- index.amber với những nội dung sau:
1 |
h3 Flat CMS News |
2 |
|
3 |
p Here is where all the news about what I am doing is found. Please come back often to check it out! |
4 |
|
5 |
mixin article($title, $link, $excerpt, $date) |
6 |
div.entry |
7 |
div.tutorial_wrap |
8 |
div.tutorial_div |
9 |
a[href=$link] |
10 |
h3 #{$title} |
11 |
h5 #{$date} |
12 |
p.tutorial_excerpt #{$excerpt} |
13 |
div.clear |
14 |
|
15 |
+article("Flat CMS is Running", "/posts/news/flatcms/flatcms", "The Flat CMS Test Server is Running!", "August 12, 2015") |
- flatcms.md với những nội dung sau:
1 |
The New Server is Running |
2 |
---- |
3 |
|
4 |
After much work and programming, I finally have everything moved over to a goPress server that I wrote myself. I will be making this available for you too. Stay tuned! |
5 |
|
6 |
{{{socialmedia}}} |
Điều này tạo ra các mục tin tức cho trang demo. Trong trang web của tôi, tôi sử dụng cấu trúc tương tự cho các bài hướng dẫn và viết code các trang demo.
Images
Tất cả các trang web đều có hình ảnh. Trong thiết lập này, tất cả các hình ảnh nằm trong thư mục site/images. Đối với trang demo này, chỉ có các hình biểu tượng mạng xã hội sẽ được đặt ở đây. Bạn có thể lấy hình ảnh từ tập tin tải về.
CSS cho Trang web
Ngay cả với css cho bố cục và css để trang trí, thì sẽ có những lúc bạn sẽ muốn có các quy tắc css đặc biệt. Thư mục site/css chứa tất cả các tập tin css mang những hoàn thiện đó vào trang web. Tất cả các tập tin trong layout, styling, và site/css sẽ được biên dịch cùng với nhau thành một tập tin css. Vì vậy, hãy tạo thư mục site/css/final để chứa tập tin đã biên dịch này. Bây giờ, tạo tập tin site/css/site.css với những nội dung sau:
1 |
.clear { |
2 |
clear: both; |
3 |
height: 0px; |
4 |
}
|
Không quá nhiều điều ở đây—chỉ là một định nghĩa cho một lớp clear
. Bạn có thể thêm những gì bạn muốn, nhưng nó phải là thứ gì đó không rơi vào danh mục bố cục hoặc kiểu dáng.
Script cho Trang web
Thư mục site/js chứa tất cả các tập tin JavaScript đặc biệt cho trang web. Những tập tin này sẽ được biên dịch lại và giảm tối đa dung lượng để tải trang web nhanh hơn. Còn bây giờ, hãy tạo thư mục site/js/final cho script đã được biên dịch và tập tin site/js/01-site.js với các nội dung sau:
1 |
;
|
2 |
//
|
3 |
// File: Site.js
|
4 |
//
|
5 |
// Description: The JavaScript file for the site.
|
6 |
//
|
7 |
jQuery(document).ready(function () { |
8 |
//
|
9 |
// Code here will be ran once a page is loaded.
|
10 |
//
|
11 |
});
|
Không có quá nhiều thứ ở đây ngay lúc này. Tuy nhiên, khi trang web của bạn cần JavaScript tùy biến, bạn có thể đặt nó ở đây.
Vì script sẽ được biên dịch lại với nhau, nên tôi đánh số chúng theo thứ tự cần nạp. Phương thức biên dịch các script lại với nhau sẽ nạp chúng theo thứ tự số.
Tự động hoá Với Gulp
Cách đơn giản nhất để tăng tốc độ tải trang là càng có ít yêu cầu HTTP nhất càng tốt. Do đó, tốt nhất là kết hợp tất cả các tập tin CSS và JavaScript thành một tập tin. Cách tốt nhất để biên dịch các tập tin này là với một build script. Thực hiện nó mỗi khi máy chủ nhận nhận được một yêu cầu là một sự lãng phí thời gian xử lý.
Lựa chọn script tự động chạy của tôi là Gulp. Gulp chạy trên Node.js. Do đó, hãy truy cập trang web Node.js và tải về chương trình cho hệ thống của bạn. Một khi bạn đã cài đặt Node.js, bạn có thể cài đặt Gulp với những lệnh sau:
1 |
npm install --global gulp |
2 |
npm install --global gulp |
3 |
npm install --global gulp-compass |
4 |
npm install --global gulp-autoprefixer |
5 |
npm install --global gulp-compressor |
6 |
npm install --global gulp-concat |
Việc này sẽ cài đặt Gulp và tất cả các mô-đun của Gulp mà tôi sử dụng trong build script. Bây giờ, ở đầu thư mục của bạn, tạo tập tin gulpfile.js với những nội dung sau:
1 |
// Requirements
|
2 |
var gulp = require('gulp'), |
3 |
compass = require('gulp-compass'), |
4 |
prefix = require('gulp-autoprefixer'), |
5 |
compressor = require('gulp-compressor'), |
6 |
concat = require('gulp-concat'); |
7 |
|
8 |
// Defines path to sass
|
9 |
var Theme = "Basic"; |
10 |
var Layout = "SingleCol"; |
11 |
var themesassRoot = 'themes/styling/' + Theme; |
12 |
var layoutsassRoot = 'themes/layouts/' + Layout; |
13 |
|
14 |
// Gulp task
|
15 |
gulp.task('theme-compass-to-css', function(){ |
16 |
return gulp.src(themesassRoot+'/sass/Basic.scss') |
17 |
.pipe(compass({ |
18 |
config_file: themesassRoot + '/config.rb', |
19 |
css: themesassRoot + '/css', |
20 |
sass: themesassRoot + '/sass', |
21 |
require: 'sassy-buttons' |
22 |
}))
|
23 |
.pipe(prefix("last 3 versions")) |
24 |
.pipe(gulp.dest(themesassRoot + '/css')) |
25 |
});
|
26 |
|
27 |
gulp.task('layout-compass-to-css', function(){ |
28 |
return gulp.src(layoutsassRoot+'/sass/base.scss') |
29 |
.pipe(compass({ |
30 |
config_file: layoutsassRoot + '/config.rb', |
31 |
css: layoutsassRoot + '/css', |
32 |
sass: layoutsassRoot + '/sass', |
33 |
require: 'susy' |
34 |
}))
|
35 |
.pipe(prefix("last 3 versions")) |
36 |
.pipe(gulp.dest(layoutsassRoot + '/css')) |
37 |
});
|
38 |
|
39 |
gulp.task('watch-compass', function(){ |
40 |
// What to watch
|
41 |
gulp.watch(themesassRoot + '/sass/Basic.scss', function(){ |
42 |
// What to run
|
43 |
gulp.run('theme-compass-to-css'); |
44 |
});
|
45 |
gulp.watch(layoutsassRoot + '/sass/Basic.scss', function(){ |
46 |
// What to run
|
47 |
gulp.run('layout-compass-to-css'); |
48 |
});
|
49 |
});
|
50 |
|
51 |
gulp.task('all-compass', ['theme-compass-to-css', 'layout-compass-to-css']); |
52 |
|
53 |
// js compressor
|
54 |
gulp.task('js', function () { |
55 |
gulp.src([ layoutsassRoot +'/js/*.js', themesassRoot + '/js/*.js', 'site/js/*.js']) |
56 |
.pipe(compressor()) |
57 |
.pipe(concat("final.js")) |
58 |
.pipe(gulp.dest('site/js/final')); |
59 |
});
|
60 |
|
61 |
// css compressor
|
62 |
gulp.task('css', ['all-compass'], function () { |
63 |
gulp.src([layoutsassRoot +'/css/*.css', themesassRoot + '/css/*.css', 'site/css/*.css']) |
64 |
.pipe(compressor()) |
65 |
.pipe(concat("final.css")) |
66 |
.pipe(gulp.dest('site/css/final')); |
67 |
});
|
68 |
|
69 |
gulp.task('default', ['all-compass', 'js', 'css']); |
Việc này sẽ biên dịch tất cả các CSS và JavaScript thành một tập tin duy nhất: tập tin site/css/final/final.css cho CSS, và tập tin site/js/final/final.js cho JavaScript. Nó cũng sẽ thêm các quy tắc tiền tố trình duyệt (browser prefix) cho CSS. Chỉ cần chạy lệnh sau trong thư mục cao nhất:
1 |
gulp |
Gulp sẽ biên dịch tất cả các tập tin của chúng ta và để chúng ở đúng vị trí. Mỗi tác vụ được định nghĩa trong tập tin gulpfile.js có thể được chạy một cách riêng lẻ bằng cách đặt tên tác vụ phía sau lệnh gulp
. Bạn có thể tìm hiểu thêm về Gulp trên Tuts+.
Tập tin Cấu hình Máy chủ
Tất cả các máy chủ đều cần thông tin cấu hình. Do đó, trong thư mục gốc, hãy tạo tập tin server.json với thông tin sau:
1 |
{ |
2 |
"CurrentLayout": "SingleCol", |
3 |
"CurrentStyling": "Basic", |
4 |
"ServerAddress": "localhost:8080", |
5 |
"SiteTitle": "Flat CMS Test Site", |
6 |
"Sitebase": "./site/", |
7 |
"TemplatBase": "./themes/", |
8 |
"Cache": false, |
9 |
"MainBase": "" |
10 |
} |
Tập tin json này mô tả thông tin về bố cục, giao diện để sử dụng, địa chỉ và cổng máy chủ sẽ lắng nghe, tên chính cho trang web với một tiêu đề phụ, một cờ Cache để bật và tắt bộ nhớ đệm cho các mục đích gỡ lỗi , và vị trí của các thư mục khác nhau được sử dụng cho trang web. Bằng cách cung cấp các thông tin này cho máy chủ trong tập tin json, máy chủ có thể linh hoạt, với ít thông tin được ghi trực tiếp.
Tải Trang web lên Máy chủ
Hầu hết mọi người đều sử dụng một FTP client để sao chép các tập tin lên máy chủ của họ. Điều này rất dễ thực hiện, nhưng khác nhau rất nhiều tuỳ theo hệ thống và các chương trình được sử dụng. Nhưng có một số lựa chọn khác.
Bạn có thể thiết lập một daemon trên Dropbox để nạp trang web từ tài khoản Dropbox của bạn. Trang Dropbox Wiki có các hướng dẫn chi tiết để thiết lập điều này. Vấn đề duy nhất là các tập tin được tự động tải lên máy chủ khi bạn thực hiện bất kỳ thay đổi nào. Đôi khi, bạn sẽ muốn thực hiện thay đổi mà không cần chúng phải chuyển lên máy chủ. Nếu đúng như vậy, bạn cũng có một vị trí không phải là Dropbox chứa tất cả các tập tin của trang web và một vị trí của Dropbox. Khi hoàn tất, tạo một tác vụ trong tập tin Gulp của bạn để sao chép các tập tin trang web mới đến vị trí của Dropbox.



Cách làm ưa thích của tôi là sử dụng Dropzone 3. Bạn có thể lập trình Dropzone 3 với Ruby hoặc Python để thực hiện bất kỳ loại hành động nào trên một tập tin được thả vào nó. Nó còn có sẵn nhiều chức năng. Có một tập tin hành động được xây dựng để tải lên một trang FTP/SFTP. Tôi tạo ra một mục tiêu Dropzone 3 cho mỗi thư mục chính trên trang web của tôi. Sau đó, khi tôi muốn thay đổi hoặc thêm một tập tin, tôi chỉ cần kéo nó vào mục tiêu dropzone của thư mục tương ứng. Bạn có thể tìm hiểu thêm về Dropzone 3 với bài viết của tôi Viết Các Hành động trong Dropzone 3.
Tóm tắt
Những tập tin cơ bản này sẽ tạo ra một trang web có giao diện như sau:



Đây chỉ mới là sự khởi đầu! Bây giờ, với cấu trúc trang web đã hình thành, đã đến lúc bắt đầu xây dựng các máy chủ web. Hãy tham gia cùng tôi trong hướng dẫn tiếp theo, nơi tôi sẽ xây dựng một máy chủ web dựa trên ngôn ngữ Go cho trang web demo này.