يتم إنشاء الكثير من الأدوات الرائعة للمساعدة في تعزيز تطور JAMstack. و يتبنى المطورون هاته الأدوات و يعملون على تطويرها و تحسينها. أحد هاته الأدوات تسمى مولدات المواقع الساكنة (Static Sites Generators). و يُعد Gridsome مثال على أحد مولدات المواقع الساكنة و الذي سنتطرق إليه في هاته المقالة.
في الفقرة أعلاه هنالك كلمة مكتوبة بالخط العريض (JAMstack). إذا لم تكن لديك أدنى فكرة بخصوص هذا المصطلح, فأقترح عليك قراءة هاته المقالة ما هو JAMstack ؟
المواقع الساكنة فعليا تعاملنا معها سابقا عندما بدأنا في تعلم مجال الويب حين كنا نلعب مع الـ HTML , CSS و بعض الجافاسكربت و كنا حينها نسمي الموقع ساكن (Static), فلم يكن هنالك تفاعل ما بين الموقع و المستخدم له . قد يتبادر إلى ذهنك لما علي إنشاء موقع ساكن بإستخدام Gridsome اذا كنت أستطيع عمل ذلك بالـ HTML, CSS و الجافاسكربت ؟!
مولدات المواقع الساكنة تقوم بإنشاء مواقع ساكنة أيضا لكن بفلسفة و مفهوم آخر يُضفي ميزات اثناء مرحلة التطوير, كما يجعل من هذا الموقع الساكن سريع جدا, عالي الحماية, قوي و مرن.
الـ Gridsome عبارة عن مولد مواقع ساكنة (SSG) مدعوم و يعتمد على إطار العمل Vue.js يعمل على إنشاء مواقع ساكنة سريعة جدا. يعتمد على طبقة GraphQL للحصول على البيانات من مصادر مختلفة من أجل إنشاء منها صفحات ديناميكية.
ملاحظة : SSG هي إختصار لـ Static Sites Generator
Gridsome هو إطار عمل لتطوير مواقع الويب يُمكننا من إنشاء مواقع ثابتة سريعة و آمنة. يقوم بجلب البيانات من مصادر بيانات كـأنظمة إدارة المحتوى (CMS), ملفات محلية (local files), APIs,... و تخزينها في قاعدة بيانات محلية. تُتيح لنا طبقة بيانات GraphQL الموحدة (تعمل GraphQL كنظام مركزي يحتوي على كل البيانات و يتم إدارة هاته البيانات من قبلها) من إستخراج البيانات التي نحتاجها فقط من قاعدة البيانات و استخدامها في مكونات vue.js المسؤولة عن عرضها. يتم إنشاء البيانات و تخزينها على شكل static JSON وقت الإنشاء (Build Time).
هنالك طريقتان لتشغيل Gridsome :
gridsome develop
تشغيل خادم تطوير محلي (local development server).gridsome build
توليد ملفات ثابتة جاهزة للإنتاج (Deploy).يقوم هذا الأمر بتشغيل خادم التطوير المحلي مع خاصية hot-reloading التي تعمل على إعادة تحميل للصفحة تلقائيا عند اي تغييرات في الكود أو الملفات. و طبقة بيانات GraphQL.
عادة خادم التطوير المحلي يشتغل على localhost:8080, و طبقة بيانات GraphQL على localhost:8080/___explore.
إليك ما يحدث وراء الكواليس عند تشغيل الأمر gridsome develop
:
Bootstrap finish -- يبدأ خادم التطوير في العمل و يُظهر عنواين Url (لتصفح كل من التطبيق أو طبقة بيانات GraphQL) في شاشة سطر الأوامر (Console).
يقوم هذا الأمر بإعداد المشروع لوضع الإنتاج (Production). هذا يعني أنه يُنشىء ملفات HTML مُحسنة و جاهزة للإستظافة و نشرها على أي FTP أو Static Web Host.
إليك ما يحدث وراء الكواليس عند تشغيل الأمر gridsome build
:
page-query
و تخزين النتائج في ملفات json
.لإتباع هاته المقالة التعليمية تحتاج إلى التالي:
Yarn
بدلا من Npm
.أول شيء سنفعله هو التحقق من تثبيت Node و npm/yarn.
node --version && npm --version
بعدها يُمكنك تثبيت أداة Gridsome CLI عن طريق تشغيل الأمر التالي:
yarn global add @gridsome/cli
أو
npm install --global @gridsome/cli
الخطوة التالية هي إنشاء مشروع جديد باستخدام CLI الذي قمنا بتثبيته للتو:
gridsome create gridsome-demo
بمجرد الانتهاء من التثبيت ، يمكننا تشغيل موقع Gridsome بهذا الأمر:
cd gridsome-demo/ && gridsome develop
يُمكنك معاينة أول موقع لك بإستخدام Gridsome على الرابط: http://localhost:8080
.
├── package.json
├── gridsome.config.js
├── gridsome.server.js
├── static/
└── src/
├── main.js
├── index.html
├── App.vue
├── layouts/
│ └── Default.vue
├── pages/
│ ├── Index.vue
│ └── Blog.vue
└── templates/
└── BlogPost.vue
يحتوي على معلومات بخصوص الإضافات و التبعيات التي يحتاجها المشروع.
يحتوي على إعدادات و خيارات للإضافات التي يتم تثبيتها.
هذا الملف إختياري و يُستخدم للوصول ﻷجزاء مختلفة من خادم Gridsome.
إستدعاء ملفات التنسيق و الإضافات يكون في هذا الملف. في هذا المكان يتم إضافة إضافات Vue, تسجيل المكونات, التوجيهات (Directives),...
هنا يتم إنشاء مكونات التخطيط العامة (Layouts Components) مثل الهيدر, القائمة الجانبية, الفوتر,...
جميع المكونات في هذا المجلد تُصبح صفحات الموقع. كل صفحة تحصل على مسارها حسب مكان ملف المكون.
هذا المكون src/pages/Index.vue
سيكون الصفحة الرئيسية للموقع, بينما src/pages/AboutUs.vue
ستكون الصفحة على المسار example.com/about-us
.
عند إستيراد او جلب بيانات من مصدر بيانات خارجي, مثلا مقالات من مدونة wordpress, إلى الموقع فإن كل مقالة سيكون لها شكل معين تظهر فيه. هذا الشكل نسميه بالقالب و هو عبارة من ملف .vue و على إسم القالب ان يتطابق مع نوع العقدة في مخطط GraphQL. فإذا كان نوع العقدة Post سيكون إسم ملف القالب Post.vue.
في بعض الأحيان نحتاج إلى التعديل على قالب HTML الأساسي الذي يوفره Gridsome الذي من خلاله يتم انشاء الصفحات. Gridsome جعل اﻷمر سهل جدا. كل ما عليك فعله هو انشاء ملف index.html جديد في مجلد /src.
يُعد ملف App.vue المكون الرئيسي الذي يحوي كل الصفحات و القوالب. يمكنك تخصيص الملف الإفتراضي من خلال إنشاء ملف App.vue في مجلد /src.
يتم نسخ الملفات الموجودة في هذا المجلد مباشرة إلى مجلد الإنتاج النهائي /dist أثناء عملية الـ build. على سبيل المثال ملف static/robots.txt
سيكون موجود على https://yoursite.com/robots.txt.
في الغالب عند التعامل مع gridsome ستحتاج إلى إستخدام إضافات تؤدي غرض معين, هاته الإضافات تأتي ببعض الخيارات التي يُمكن التعديل عليها بما يُناسب. في هاته المقالة سنعمل على إنشاء مدونة بسيطة و سنعتمد على تخزين المقالات في ملفات markdown, و بالتالي سنحتاج إلى تسطيب الإضافة التي تسمح لك بذلك. (مدونة سينتاكس تم برمجتها بإستخدام Gridsome و تستخدم ملفات markdown في تخزين المقالات. فقط حتى تعرف ما قد يمكنك فعله, بغض النظر عن المدونة البسيطة التي سنقوم بإنشائها في هذا المقال.)
الإضافات الخاصة بالـ Gridsome تجدها على الرابط التالي : Plugins
نحتاج إلى تثبيت بعض الإضافات المساعدة :
yarn add @gridsome/transformer-remark
yarn add @gridsome/source-filesystem
أو
npm install @gridsome/transformer-remark
npm install @gridsome/source-filesystem
تعمل إضافة gridsome/transformer-remark@
على تحويل ملفات markdown إلى كود HTML يُمكن عرضه في الموقع.
تعمل إضافة gridsome/source-filesystem@
على تحويل الملفات إلى محتوى يُمكن جلبه من خلال GraphQL إلى المكونات (components).
و بعدها نحتاج إلى التعديل على ملف gridsome.config.js :
module.exports = {
siteName: "simple blog",
plugins: [
{
use: "@gridsome/source-filesystem",
options: {
path: "content/posts/**/*.md",
typeName: "Post",
},
},
],
templates: {
Post: "/posts/:title",
},
};
هنا نُخبر Gridsome أن يقوم بإستخدام gridsome/source-filesystem@
مع تعديل بعض الخيارات (Options) :
(md.*/**/)
.vue
في المسار src/templates
يجب ان يُطابق هذا الإسم.title:
.أما بالنسبة لـ gridsome/transformer-remark@
بمجرد تثبيته في المشروع يتم إستخدامه بشكل تلقائي.
في هذا التطبيق سوف أعتمد على إطار العمل Tailwindcss من أجل تنسيق المكونات. هنالك إضافة تُمكننا من تضمين tailwindcss في الموقع بكل بساطة, لكن نحن سنقوم بتضمينه بدون أي إضافة.
أولا نحتاج إلى تثبيت حزمة tailwindcss في المشروع من خلال الأمر :
yarn add tailwindcss
or //
npm i tailwindcss
ثانيا نحتاج إلى إنشاء ملف إعداد tailwindcss (خطوة إختيارية - تحتاج لهذا الملف إذا ما أردت التعديل في هذا الإطار) من خلال الأمر :
npx tailwind init
الأمر السابق سيقوم بإنشاء لنا ملف tailwind.config.js في المجلد الجذر (root directory).
ثالثا سوف نحتاج إلى تضمين Tailwindcss في Gridsome (المشروع) عن طريق إنشاء ملف و لنُسمه tailwind.css في المسار assets/css
و إضافة إليه التالي :
@tailwind base;
@tailwind components;
@tailwind utilities;
و بعدها نقوم بإضافته في ملف main.js
// Import tailwindcss
import "~/assets/css/tailwind.css";
import DefaultLayout from "~/layouts/Default.vue";
export default function(Vue, { router, head, isClient }) {
// Set default layout as a global component
Vue.component("Layout", DefaultLayout);
}
و آخـرا نُضيف الـ tailwindcss إلى ملف إعدادات gridsome:
const tailwindcss = require("tailwindcss");
module.exports = {
siteName: "simple blog",
plugins: [
// ...
],
css: {
loaderOptions: {
postcss: {
plugins: [tailwindcss],
},
},
},
};
نقوم بتشغيل الموقع عن طريق تنفيذ الأمر التالي gridsome develop
و زيارة الرابط http://localhost:8080/
, ستكون لدينا صفحة عرض بالشكل التالي:
لدينا الملف src/pages/Index.vue
المسؤول عن عرض الصفحة الرئيسية للموقع.
نقوم بالتعديل عليه بالشكل الآتي:
<template>
<Layout> </Layout>
</template>
<script>
export default {
metaInfo: {
title: "index page",
},
};
</script>
في جزئية الـ metaInfo
قُمنا بتغيير عنوان الصفحة الحالية التي نحن فيها. طبعا يُمكن تعديل الكثير لكن نكتفي بهذا القدر حاليا. ليكون لدينا الناتج التالي:
قد يتبادر إلى ذهنك أين يتواجد هذا النافبار (navbar)!!
هاته هي قوة الـ Layouts إذ تسمح لنا بمشاركة مكونات عادة ما تكون متكررة في كل الصفحات مثل الهيدر, الفوتر, ...
نأتي على المسار src/layouts/Default.vue
و نُضيف الكود التالي:
<template>
<div class="layout">
<h1 class="text-5xl mt-4">Gridsome Blog</h1>
<p class="mb-24 font-bold">
A simple blog designed with Gridsome
</p>
<slot />
<footer class="mt-24 font-bold">
built with <strong>Gridsome</strong>
</footer>
</div>
</template>
<style>
body {
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI",
Roboto, "Helvetica Neue", Arial, sans-serif;
margin: 0;
padding: 0;
line-height: 1.5;
}
.layout {
max-width: 760px;
margin: 0 auto;
padding-left: 20px;
padding-right: 20px;
text-align: center;
}
footer strong {
color: #4caf50;
}
</style>
فيُصبح لدينا الشكل التالي:
نكتفي بهذا القدر بالنسبة لشكل الصفحة الرئيسية. الآن ما بين الهيدر و الفوتر نُريد عرض قائمة تحتوي المقالات. لهذا سنقوم بإنشاء مُكون جديد على المسار src/components
بإسم PostList.vue
و نضيف له التالي:
<template>
<div class="post-list">
<hr class="my-6" />
<p v-html="post.date" />
<h1 v-html="post.title" class="text-xl font-bold my-2" />
<p v-html="post.description" />
<g-link :to="post.path" class="font-bold text-green-500 mt-4 block"
>Read More...</g-link
>
</div>
</template>
<script>
export default {
props: ["post"],
};
</script>
هذا المكون سنضيف إليه لاحقا عند تضمينه في الصفحة الرئيسية حلقة تكرارية حتى يتم تكراره بعدد المقالات الموجودة, فجميع المقالات نريد عرضها بنفس الشكل في القائمة.
نعود الآن على الصفحة الرئيسية أين سنقوم بعرض جميع المقالات و نُضيف لها المكون الذي قمنا بإنشائه قبل قليل.
<template>
<Layout>
<section>
<PostList
v-for="edge in $page.allPost.edges"
:key="edge.node.id"
:post="edge.node"
/>
</section>
</Layout>
</template>
<page-query>
query { allPost { totalCount edges { node { id title description date (format:
"D MMMM YYYY") path } } } }
</page-query>
<script>
import PostList from "~/components/PostList.vue";
export default {
metaInfo: {
title: "index page",
},
components: {
PostList,
},
};
</script>
حتى نستطيع جلب البيانات التي يتم إستخراجها من الملفات المحلية mardown من خلال طبقة بيانات GraphQL. سنحتاج إلى كتابة الإستعلامات بين <page-query>
و </page-query>
. هاته طريقة جلب البيانات من خلال GraphQL. إذا ما أردت تجريب ذلك بطريقة تفاعلية و ترى ماذا ترجعه هاته الإستعلامات. إفتح الرابط http://localhost:8080/___explore لكن قبل هذا نحتاج إلى إضافة بعض الملفات التي تحتوي على المقالات. سنقوم بإنشاء مجلد جديد على المسار /content/posts/.
و ننشىء ملفين كالتالي:
---
title: "Say hello to Gridsome 🎉"
date: 2019-02-07
description: "A new static site generator baby is born. It's highly inspired by Gatsby.js (React based) but built on top of Vue.js. We have been working on it for a year and will have a beta ready soon. You can expect this baby to grow up fast!"
---
A new static site generator baby is born. It's highly inspired by Gatsby.js (React based) but built on top of Vue.js. We have been working on it for a year and will have a beta ready soon. You can expect this baby to grow up fast!
We think **Gridsome** is a missing piece to the Vue.js ecosystem. What Gatsby.js does for React.js is a game changer in how we build websites. React.js is excellent, but we think Vue.js is more approachable for most web designers and devs getting started with JAMstack. Gridsome is the Vue.js alternative to Gatsby.
With **Gridsome** you get a **universal GraphQL layer** for all your connected data sources. It's like a single source of truth for your website data ready to be used in any page or components. Connect to any CMS or APIs like Google Spreadsheet, Airtable, Instagram Feed, local markdown files, etc.
---
title: "Markdown test file"
date: 2020-08-21
description: "Markdown is intended to be as easy-to-read and easy-to-write as is feasible. Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it's been marked up with tags or formatting instructions."
---
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.Readability, however, is emphasized above all else. A Markdown-formatted
document should be publishable as-is, as plain text, without looking
like it's been marked up with tags or formatting instructions.
While Markdown's syntax has been influenced by several existing text-to-HTML
filters -- including [Setext](http://docutils.sourceforge.net/mirror/setext.html), [atx](http://www.aaronsw.com/2002/atx/), [Textile](http://textism.com/tools/textile/), [reStructuredText](http://docutils.sourceforge.net/rst.html),
[Grutatext](http://www.triptico.com/software/grutatxt.html), and [EtText](http://ettext.taint.org/doc/) -- the single biggest source of
inspiration for Markdown's syntax is the format of plain text email.
بعد الدخول على http://localhost:8080/___explore نضيف الإستعلام السابق و نرى النتيجة على اليمين :
الآن سيتم عرض لنا المقالات التي تم جلبها بهذا الشكل 🎉
بقيت لدينا آخر خطوة و هي عرض كل مقالة على حدى. لهذا سنقوم بإنشاء ملف جديد في المسار src/templates/Post.vue
و نضيف له التالي:
<template>
<Layout>
<br />
<g-link to="/" class="font-bold text-red-500">
← Go Back
</g-link>
<div>
<h1 class="text-5xl my-4">
{{$page.post.title}}
</h1>
<p class="font-bold italic underline mb-2">
{{ $page.post.date}}
</p>
</div>
<div class="leading-7 mt-10">
<p v-html="$page.post.content" />
</div>
</Layout>
</template>
<page-query>
query Post ($path: String!) {
post: post (path: $path) {
id
title
content
date
(format: "D MMMM YYYY")
}
}
</page-query>
الآن بالضغط على زر ...Read More
سيتم عرض لنا المقالة مُفردة بهذا الشكل:
بعد إنشاء موقع أيا ما كان, أكيد نريد أن نقوم برفعه على الأنترنت ليراه العالم. لهذا سنقوم بإستخدام إستظافة Netlify. أفترض أنك قُمت برفع المشروع على موقع GitHub. العملية سهلة جدا كل ما عليك القيام به هو إتباع الخطوات الآتية:
نضغط على زر New site from Git
نقوم بإختيار مكان رفع المشروع. في حالتنا سنختار GitHub
نختار إسم المستودع الذي رفعنا عليه المشروع, إذا لم يظهر لك أي اسم مستودع قم بالضغط على كلمة Configure the Netlify app on Github و قُم بإعطاء الصلاحيات للوصول إلى كل المستودعات أو يُمكنك إختيار مستودع محدد
نختار المستودع الذي يحمل المشروع بعد ظهوره في القائمة
نحتاج في هاته الخطوة إلى تعريف شيئان مهمان و هما أمر إنشاء نسخة الإنتاج لأنها هي التي يتم إستظافتها و المجلد الذي سيحتوي على نسخة الإنتاج و عادة يكون مجلد dist
و تضغط على زر Deploy site.
العملية تستغرق بضع دقائق فقط. ننتظر أن تتغير كلمة Building إلى Published.
و مبروك عليك 🎉 أول موقع لك بإستخدام Gridsome. نفتح الرآبط التالي لمعاينته أونلاين https://keen-tesla-1c5005.netlify.app
في هاته المقالة تطرقنا لعمل مدونة بسيطة بإستخدام Gridsome و الإعتماد على ملفات markdown في تخزين المقالات و كيف تعمل الإضافات على تسهيل تحويل الملفات و جلبها عن طريق GraphQL. مرورا بطريقة إنشاء المكونات التي تعرضها لنا وصولا إلى رفع المدونة أونلاين.
طبعا هنالك الكثير لم نتطرق له بعد و هذا يأتي بعمل مشاريع متنوعة تغطي معظم ميزات Gridsome. هنالك 3 مشاريع سنُوفرها في قسم الدورات و التي ستغطي أشياء متقدمة في Gridsome. أتمنى أنكم إستفدتم من هاته المقالة, نلتقي في مقالات قادمة و دمتم في رعاية الله.