Lời mở đầu
Hôm nay mình xin chia sẻ về 1 công cụ giúp ta tạo ra các website tĩnh 1 cách linh hoạt . Trong thời buổi công nghệ đang chuyển biến mạnh, rất nhiều các công cụ sinh ra để phục vụ mục đích cho dân lập trình . Đối với tạo website tĩnh rất nhiều framework hỗ trợ như là Nuxt, Hugo, Jigsaw. Phạm vi bài viết này mình xin nói về Jigsaw – Một công cụ mình thấy khá gọn và cú pháp dễ hiểu nhất là đối với ai đã từng làm việc qua Laravel . Start thôi :d
Cài đặt
Với Jigsaw chúng ta có thể cài đặt thông qua composer bằng lệnh sau
1 2 3 | $ mkdir my-site && cd my-site $ composer require tightenco/jigsaw |
Xong, chúng ta chạy lệnh dưới đây để tiến hành tạo ra cấu trúc thư mục của Jigsaw
1 2 | $ ./vendor/bin/jigsaw init |
Cấu trúc thư mục sau khi đã được tạo ra, chúng ta sẽ làm việc chủ yếu ở thư mục source
Biên dịch và cấu hình
Tiến hành build ra trang web tĩnh ta có thể chạy lệnh sau từ thư mục gốc của dự án
1 2 | $ ./vendor/bin/jigsaw build |
Hoặc cho môi trường production
1 2 | $ ./vendor/bin/jigsaw build production |
Sau đó ta có thể chạy lệnh sau để tiến hành theo dõi sản phẩm của mình
1 2 | $ ./vendor/bin/jigsaw serve |
Trong trường hợp chúng ta sử dụng Laravel Mix để biên dịch
1 2 | $ npm install && npm run watch |
Mặc định tính năng Laravel Mix trong jigsaw sẽ mix các file js css từ thư mục source/_assets
tới source/assets/build
để sửa các đường dẫn này chúng ta sẽ tìm tới file webpack.mix.js
Jigsaw cũng hỗ trợ cho ta cấu hình các biến môi trường tại file config.php
, ngoài ra có những biến ta cấu hình riêng cho production thì ta sẽ tạo ra 1 file config.production.php
, trong này ta chỉ cần cấu hình các biến thay đổi về bản chất jigsaw sẽ tự gộp tất cả các biến môi trường ở 2 file và sẽ ghi đè các biến được khai báo trong config.production.php
1 2 3 4 5 6 7 8 | <span class="token comment">// Example config.php</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'production'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'baseUrl'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">''</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'collections'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'titleWeb'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">'Sun Asterisk VN'</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> |
1 2 3 4 5 | <span class="token comment">// Example config.production.php</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'production'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> |
Chúng ta có thể gọi các biến này trong Blade Template Engine ( Sẽ được giới thiệu ngay dưới đây thôi ) theo cú pháp sau :
1 2 3 4 5 6 7 | @<span class="token function">section</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'body'</span><span class="token punctuation">)</span> <span class="token operator"><</span>h1<span class="token operator">></span>Post Example<span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span> <span class="token operator"><</span>p<span class="token operator">></span> <span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">$page</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">titleWeb</span> <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> @endsection |
Tạo nội dung
Jigsaw hỗ trợ biên dịch từ file Markdown và Blade Template engine rất thuận tiện cho việc tạo nội dung , với những bạn nào đã sử dụng qua Laravel chắc chả còn xa lạ gì nữa nhỉ
Trước hết chúng ta sẽ có 1 file master.blade.php
trong thư mục source/_layouts
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token operator"><</span><span class="token operator">!</span><span class="token constant">DOCTYPE</span> html<span class="token operator">></span> <span class="token operator"><</span>html lang<span class="token operator">=</span><span class="token double-quoted-string string">"en"</span><span class="token operator">></span> <span class="token operator"><</span>head<span class="token operator">></span> <span class="token operator"><</span>meta charset<span class="token operator">=</span><span class="token double-quoted-string string">"utf-8"</span><span class="token operator">></span> <span class="token operator"><</span>meta name<span class="token operator">=</span><span class="token double-quoted-string string">"viewport"</span> content<span class="token operator">=</span><span class="token double-quoted-string string">"width=device-width, initial-scale=1, shrink-to-fit=no"</span><span class="token operator">></span> <span class="token operator"><</span>meta http<span class="token operator">-</span>equiv<span class="token operator">=</span><span class="token double-quoted-string string">"x-ua-compatible"</span> content<span class="token operator">=</span><span class="token double-quoted-string string">"ie=edge"</span><span class="token operator">></span> <span class="token operator"><</span>link rel<span class="token operator">=</span><span class="token double-quoted-string string">"stylesheet"</span> href<span class="token operator">=</span><span class="token double-quoted-string string">"{{ mix('css/main.css', 'assets/build') }}"</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>head<span class="token operator">></span> <span class="token operator"><</span>body<span class="token operator">></span> @<span class="token keyword">yield</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'body'</span><span class="token punctuation">)</span> <span class="token operator"><</span><span class="token operator">/</span>body<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>html<span class="token operator">></span> |
Tiếp là 1 file nội dung sẽ kế thừa từ master.blade.php
như khi chúng ta code View trong Laravel vậy
1 2 3 4 5 6 7 8 9 | <span class="token shell-comment comment"># File : post.blade.php</span> @<span class="token keyword">extends</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'_layouts.master'</span><span class="token punctuation">)</span> @<span class="token function">section</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'body'</span><span class="token punctuation">)</span> <span class="token operator"><</span>h1<span class="token operator">></span>Post Example<span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span> <span class="token operator"><</span>p<span class="token operator">></span> <span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">$page</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">titleWeb</span> <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> @endsection |
Note :
Biến $page trên mặc định từ Jigsaw, trong ví dụ trên ta thấy nó truy cập vào thuộc tính titleWeb từ file config.php
Ngoài ra chúng ta có thể gọi 1 số phương thức sau từ $page
1 2 3 4 5 | $page->getPath() : trả về đường dẫn trang hiện tại từ thư mục gốc $page->getUrl() : trả về URL đầy đủ nếu baseUrl được cấu hình trong config.php $page->getFilename() : trả về tên tệp của trang, không có phần mở rộng $page->getExtension() : trả về phần mở rộng của trang hiện tại |
Và 1 file Markdown content.md
( lưu ý là chúng ta thay đổi phần extends với section tương ứng với thư mục của dự án nhé )
1 2 3 4 5 6 7 8 | --- extends: _layouts.master section: body --- ### Sun Asterisk https://sunasterisk.vn  |
Tiến hành biên dịch thôi
1 2 | $ ./vendor/bin/jigsaw build |
Ta sẽ thấy có 1 folder build_local
xuất hiện và các file blade cũng như markdown đã được biên dịch thành các thư mục kèm file index.html chứa nội dung bên trong build_local
Đối với một người học về laravel như mình thì mình khá thích cách viết nội dung của Jigsaw như này :d Nhưng còn một thắc mắc nhỏ , trong master.blade.php
có thể sử dụng yield để cho các view con có thể kế thừa nội dung từ master layouts. Vậy mình có thể sử dụng @include như trong Laravel để chèn Header hay Footer được không nhỉ. Chắc chắn rồi đều từ 1 Blade engine ra thì mình nghĩ là làm được thôi. Cùng thử nhé :d
Đầu tiên mình tạo thư mục _partials
và có file header.blade.php
( lưu ý là tên thư mục các bạn để thế nào cũng được nhé , và cho chúng nằm trong /source )
1 2 3 | # Ex : _partials/header.blade.php <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span>Header Content<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</span><span class="token punctuation">></span></span> |
Tiếp đến ở master.blade.php
mình sửa lại thành như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token operator"><</span><span class="token operator">!</span><span class="token constant">DOCTYPE</span> html<span class="token operator">></span> <span class="token operator"><</span>html lang<span class="token operator">=</span><span class="token double-quoted-string string">"en"</span><span class="token operator">></span> <span class="token operator"><</span>head<span class="token operator">></span> <span class="token operator"><</span>meta charset<span class="token operator">=</span><span class="token double-quoted-string string">"utf-8"</span><span class="token operator">></span> <span class="token operator"><</span>meta name<span class="token operator">=</span><span class="token double-quoted-string string">"viewport"</span> content<span class="token operator">=</span><span class="token double-quoted-string string">"width=device-width, initial-scale=1, shrink-to-fit=no"</span><span class="token operator">></span> <span class="token operator"><</span>meta http<span class="token operator">-</span>equiv<span class="token operator">=</span><span class="token double-quoted-string string">"x-ua-compatible"</span> content<span class="token operator">=</span><span class="token double-quoted-string string">"ie=edge"</span><span class="token operator">></span> <span class="token operator"><</span>link rel<span class="token operator">=</span><span class="token double-quoted-string string">"stylesheet"</span> href<span class="token operator">=</span><span class="token double-quoted-string string">"{{ mix('css/main.css', 'assets/build') }}"</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>head<span class="token operator">></span> <span class="token operator"><</span>body<span class="token operator">></span> @<span class="token keyword">include</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'_partials.header'</span><span class="token punctuation">)</span> <span class="token comment">// hoặc @include('_partials.header', ['page_title' => 'My Website'])</span> <span class="token comment">// Nếu mình muốn truyền các biến qua bên header, khi đó trang header mình sẽ gọi $nameVar tương ứng</span> @<span class="token keyword">yield</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'body'</span><span class="token punctuation">)</span> <span class="token operator"><</span><span class="token operator">/</span>body<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>html<span class="token operator">></span> |
Save lại thôi nào , mình sử dụng npm run watch
trong quá trình dev nên khi save nó sẽ tự build cho mình
Làm việc với collection
Làm gì đó thú vị hơn đi , thử lấy các post từ 1 API Json về xem thế nào nhỉ 😕
Mình vào sửa config.blade.php
như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'production'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'baseUrl'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">''</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'collections'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'reddit'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'extends'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">'_layouts.reddit'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'items'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$posts</span> <span class="token operator">=</span> <span class="token function">json_decode</span><span class="token punctuation">(</span><span class="token function">file_get_contents</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'https://www.reddit.com/r/aww.json?raw_json=1'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">collect</span><span class="token punctuation">(</span><span class="token variable">$posts</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">data</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">children</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$post</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'id'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">data</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">id</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'title'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">data</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">title</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'thumbnail'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">data</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">thumbnail</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'content'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token double-quoted-string string">""</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> </span> |
Ở trên mình có 1 item reddit trong biến collections , ở đây mình khai báo extends để nó sẽ hiển thị nội dung theo 1 file template nào đó ( trong ví dụ này của mình là _layouts/reddit.blade.php )
và trong các items mình sẽ viết 1 function lấy về các bài viết từ 1 file json sau đó map chúng ra các trường dữ liệu mình cần 😕
Và cuối cùng trong file template mình liệt kê danh sách các items như khi làm view trong laravel , dùng @foreach XD
1 2 3 4 5 6 7 8 9 10 11 12 | @<span class="token keyword">extends</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'_layouts.master'</span><span class="token punctuation">)</span> @<span class="token function">section</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'body'</span><span class="token punctuation">)</span> <span class="token operator"><</span>h1<span class="token operator">></span>Post Example<span class="token operator"><</span><span class="token operator">/</span>h1<span class="token operator">></span> <span class="token operator"><</span>p<span class="token operator">></span> <span class="token operator"><</span>ul<span class="token operator">></span> @<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$reddit</span> <span class="token keyword">as</span> <span class="token variable">$post</span><span class="token punctuation">)</span> <span class="token operator"><</span>li<span class="token operator">></span><span class="token operator"><</span>a href<span class="token operator">=</span><span class="token double-quoted-string string">"{{ <span class="token interpolation"><span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">getUrl</span></span>() }}"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">title</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span> @<span class="token keyword">endforeach</span> <span class="token operator"><</span><span class="token operator">/</span>ul<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> @endsection |
Và đây là kết quả
Jigsaw còn hỗ trợ rất nhiều các function khác như phân trang , lọc , sắp xếp bla bla
Bài viết của mình còn thiếu xót nhiều lắm mong các bạn đóng góp thêm để mình cải thiện cho các bài sau . Hy vọng với những gì mình tìm hiểu và chia sẻ , các bạn sẽ có thêm những công cụ tuyệt vời hơn trong con đường làm web của mình !