دليل أسطرلاب English GitHub

وضع المدونة

المدونة الجاهزة: ترويسة الموقع وصفّ المواضيع، وصفحات المقالات، والصفحة الرئيسية على هيئة مجلة، وخلاصة RSS، ووسوم محركات البحث.


يستطيع أسطرلاب أن يعرض ملاحظاتك المنشورة للزوار على هيئة مدونة تقليدية. شغّل ذلك بـPUBLIC_LAYOUT=blog، أو من الإعدادات ← النشر ← التخطيط العام ← مدونة. عندها يرى الزوار:

  • ترويسة في أعلى كل صفحة، تحمل اسم الموقع وشعاره النصي (SITE_TAGLINE)؛
  • صفًّا أفقيًا من المواضيع، موضوعًا لكل وسم؛
  • صفحات مقالات لكل منها عنوان وتاريخ وعدد كلمات ووقت قراءة تقريبي ووسوم الملاحظة، وتحتها التعليقات إذا كان COMMENTS=on؛
  • تذييلًا (SITE_FOOTER، وقيمته الافتراضية © <year> <SITE_NAME>؛ اكتب فيه {year} و{siteName} فيُملآن لك تلقائيًا).

تُعرض المقالة العربية من اليمين إلى اليسار والإنجليزية من اليسار إلى اليمين، كلّ على حدة. وإذا كان الموقع كله عربيًا فإن SITE_LANG=ar يعكس إطار المدونة أيضًا (انظر العربية والكتابة من اليمين). ولا يمسّ شيء من هذا حسابك أنت بوصفك المدير المسجَّل: يبقى لك التطبيق كاملًا بلوحته الجانبية وكل شيء. فالمدونة هي ما يراه الزوار فحسب.

أما تواريخ التدوينات فتأخذ أسماء الشهور من لغة الواجهة (الواجهة الإنجليزية تقول August والعربية تقول أغسطس)، وتأخذ الأرقام من إعداد الأرقام في نسختك من التطبيق. وذلك الإعداد هو BLOG_LOCALE: رمز لغة بالمعيار BCP 47، مثل en أو ar (وقيمته الافتراضية en)، وهو أيضًا لغة خلاصة RSS.

الصفحة الرئيسية بلوحة المعلومات

تبدأ الصفحة الرئيسية بملاحظة HOME_NOTE معروضةً مقدمةً للموقع، إذا كانت تلك الملاحظة منشورة. وتحتها قائمة التدوينات، الأحدث أولًا. ولكل موضوع صفحته على /topic/<tag>. أما عنوان المقالة فهو عنوان الملاحظة العادي نفسه، ولا يتغير فيه شيء.

ما الذي يُعدّ تدوينة

كلّ ملاحظة فيها publish: true تدوينة، وتُرتَّب القائمة من الأحدث إلى الأقدم. ويُحدَّد تاريخ التدوينة بهذا الترتيب:

  1. المقدمة. (المقدمة هي الكتلة الواقعة بين سطرَي --- في أعلى الملاحظة.) يُقرأ date: أو created: أو published:، أيّها وُجد أولًا وأمكن قراءته تاريخًا. ويصلح تاريخ YAML المجرد مثل 2024-05-01 كما يصلح النص بين علامتي اقتباس أو بصيغة ISO.
  2. id: رقمي، إذا كان قالب الملاحظة قد أنشأه. هذا المعرّف هو لحظة إنشاء الملاحظة بالضبط (Date.now() مكمَّلًا بالأصفار إلى الطول الذي طلبه القالب). وهو أصدق وقت إنشاء يمكن أن تحمله ملاحظة: أقدم من كل ما يعرفه القرص أو السجل المذكور أدناه، ولا يتأثر بنقل الملفات داخل الخزانة.
  3. اللحظة التي رأت فيها هذه النسخة الملاحظة أول مرة. وهذه ليست وقت إنشاء الملف كما يبلّغه القرص اليوم. فكلّ حفظ يكتب ملفًا مؤقتًا ثم يعيد تسميته ليحل محل الملاحظة، ونظام التشغيل يعامل ذلك على أنه ملف جديد تمامًا، فيصير وقت «الإنشاء» على القرص في الحقيقة وقت آخر تعديل. لذلك تتذكر النسخة أول وقت إنشاء صادفته لكل مسار، في ASTROLABE_DATA/created.json. وإذا كانت الخزانة مستودع git ملأت تلك الذاكرة من الإيداع الذي أضاف الملف أول مرة، فتستعيد الخزانة القديمة التي شُغّل فيها النسخ الاحتياطي تواريخها الحقيقية. أما الخزانة التي نُقلت بنسخ الملفات، بلا تاريخ git، فما زالت تحتاج إلى date: في المقدمة، وإلا بدت تدويناتها كلها كأنها أُنشئت يوم النسخ.

والمقتطف الذي يظهر في القوائم هو أول فقرة نثر حقيقية: تُنزع علامات ماركداون، وتُتخطى بقايا القوالب مثل طابع زمني مجرد أو سطر Tags: #a #b. ويُقطع عند نحو 220 حرفًا، عند نهاية كلمة. ويقدّم GET /api/posts القائمة.

ولا تظهر ملاحظات مجلد القوالب أبدًا في قائمة التدوينات ولا في الخلاصة ولا في لوحة المعلومات، حتى لو حملت publish: true لترثه الملاحظات المصنوعة منها.

اضبط EXCLUDE_TAGS قبل أن تنشر موقعك. يُبنى صف المواضيع من وسوم ملاحظاتك المنشورة، وهذا يشمل وسوم سير العمل: علامات الحالة مثل #draft أو #seedling، ووسوم نضج الملاحظة، وحالات المهام. فإن تركتها صارت فئات عامة. أدرجها في EXCLUDE_TAGS فتختفي من صف المواضيع وصفحات المواضيع وشرائح الوسوم على المقالات. ولا تتأثر خزانتك ولا عرض المدير.

الشريط سطر واحد دائمًا

مهما بلغ عدد المواضيع التي تجمعها وسومك، يبقى صف المواضيع سطرًا واحدًا. يقيس الصف نفسه، ويُبقي المواضيع التي تتسع، ويطوي الباقي في قائمة «المزيد ▾» بجانبها. ويعيد القياس مع كل تغيير في الحجم، تكبيرًا أو تصغيرًا، فلا يلتف أبدًا إلى سطر ثانٍ مهلهل. وحين يقلّ العرض عن نحو 840px تنتقل المواضيع إلى القائمة المطوية المعتادة (زر ☰) التي تعرضها كلها معًا.

المجموعات لا تنطوي. حين يحمل الصف أيضًا شرائح المجموعات (انظر القسم التالي)، تبقى «الرئيسية» وتلك الشرائح في الشريط بكل عرض؛ وإذا زادت عمّا يتسع له الهاتف انزلق الصف جانبيًا. المواضيع وحدها هي التي تنطوي. والسبب: المجموعة شيء أعلنتَه أنت جزءًا من بنية الموقع، وبنيةٌ تُخفى خلف قائمة عنوانها المواضيع تكون قد أُنزلت إلى مرتبة موضوع عادي. ويفصل بين الفريقين خطّ رفيع، وإلا بدت المجموعة GAMES والموضوع games شريحة واحدة مكررة.

ويظهر الموضوع تحت تسميته المحلية إن كانت له واحدة، ويحتفظ عنوانه بالاسم الأصلي.

المجلدات العامة المخصصة

المجموعات وبطاقات معرض موقع الكاتب متاحة أيضًا في الوضع المصمَّم، بإعدادات الظهور والموضع نفسها.

من أين تأتي الفئات؟ هذا هو الخيار الأول في أعلى القسم: الوسوم (موضوع لكل وسم، وهو الافتراضي) أو المجلدات (ترتيب الخزانة نفسه).

تحت المجلدات تأخذ كل ملاحظة منشورة مجلدها الأب فئةً لها. يصير اسم المجلد عنوان الفئة (وتُنزع بادئة الترتيب مثل 2| )، وتصير العلامة التي أعطيتها للمجلد في شجرة الملاحظات علامةَ الفئة، ومن ذلك وحده يأتي شريط التنقل وشريط الصفحة الرئيسية وصفحة كل فئة. وملاحظات جذر الخزانة بلا فئة. وتغادر مواضيعُ الوسوم شريطَ التنقل، وإن بقيت الوسوم ظاهرة على التدوينات. ويمكن لملاحظة المجلد (ملاحظة باسم المجلد، أو index.md داخله) أن تعطي الفئة description: وtitle: وicon: وhidden: true، من الخزانة نفسها. ولا وجود للمجموعات في هذا الوضع؛ فالمجلدات هي الفئات.

وتحت الوسوم تحصل على المجموعات. المواضيع هي ما تقوله ملاحظاتك عن نفسها، عبر وسومها. أما المجموعة فهي ما تقوله أنت عن طائفة من الملاحظات: الألعاب، القراءة، الملاحظات الميدانية، أو أيًّا كان ما يدور حوله موقعك حقًّا. فالمجموعة موضوع مصنوع باليد، له مكانه في شريط التنقل بجانب المواضيع التلقائية.

شغّل المجموعات من الإعدادات ← المجموعات. لكل مجموعة عنوان، وعنوان صفحة (/folder/<slug>)، وعلامة واحدة من طقم الرموز نفسه الذي تستخدمه شجرة الملاحظات، وسطر وصف اختياري. ويمكنك أن تُنشئ حتى اثنتي عشرة مجموعة، بالترتيب الذي ترتّبها به، وذلك هو الترتيب الذي يلقاها به القرّاء.

المجموعة صفحةُ وسم. تعلنها في الخزانة لا في الإعدادات: أنشئ ملاحظة في مجلد وسومك (مثلًا 2 - Tags/games.md) وضع في مقدمتها collection: true، وإن شئت أضف icon: وdescription: وtitle: وhidden: true وfolder: (مجلد في الخزانة تنتمي كلّ ملاحظاته المنشورة إلى المجموعة). فالوسم هو المجموعة: كلّ ملاحظة تحمل #games فيها، وشريحة المجموعة في شريط التنقل تحل محل شريحة الوسم. ولا يُكتب شيء في الإعدادات؛ فاللوحة تسرد ما أعلنته الخزانة فحسب.

من الشجرة، بلا كتابة. انقر بالزر الأيمن على مجلد واختر أنشئ موضوعًا من هذا المجلد… فتُكتب صفحة الوسم لك، بعلامة المجلد في الشجرة وfolder: مضبوطًا سلفًا. وانقر بالزر الأيمن على ملاحظة واختر المجموعات… لتؤشّر على المجموعات التي تنتمي إليها، فيُكتب سطر tags: لك (أو folders: في الملاحظات الأقدم). والعضوية الآتية من المجلد تظهر مؤشَّرًا عليها وتبقى كذلك.

إنشاء موضوع لا ينشر شيئًا، والنشر لا ينشئ موضوعًا. الأمران منفصلان عمدًا، والقائمة تسميهما باسمين مختلفين. أعضاء الموضوع هم ملاحظات مجلده المنشورة أصلًا، وأيّ ملاحظة تحمل وسمه. فالموضوع الذي تنشئه فوق مجلد من الملاحظات الخاصة صفحة فارغة (والمكتبة تسلك السلوك نفسه للسبب نفسه). ولنشر الملاحظات انقر بالزر الأيمن على المجلد واختر انشر كل ملاحظة في هذا المجلد…. يسألك أولًا ويخبرك بعدد الملاحظات، ثم يكتب publish: true في كل ملاحظة تفتقده، ملاحظةً ملاحظة، عبر الطريق نفسه الذي تسلكه علامة ✦ في شريط الحالة. والملاحظات المنشورة أصلًا تُترك كما هي.

ويمكن للملاحظة أن تنضم إلى مجموعة من مقدمتها هي أيضًا، وكل صيغة يجيزها YAML تعمل:

---
title: Elden Ring, finished
publish: true
folders: [games, long-reads]
---
folders: games          # مجلد واحد
folder: games           # المفتاح المفرد يُقرأ أيضًا
folders: games, books   # قائمة بفواصل
folders:                # قائمة كتلية
  - games
  - books

وملاحظة .tex تعلن الشيء نفسه في كتلة التعليق الخاصة بها، كما تعلن أي مفتاح آخر من مفاتيح المقدمة. العناوين حروف لاتينية صغيرة وأرقام وشرطات؛ ويُغفر اختلاف حالة الأحرف والمسافات الزائدة و/folder/games/ الملصوق كما هو. والعنوان الذي لا تعلنه أي مجموعة لا يطابق شيئًا، لا أكثر، وهذا ما يتيح لك أن تكتب المقدمة أولًا وتُنشئ المجموعة لاحقًا.

ويقرر مفتاحان أين تظهر المجموعات:

  • إظهارها في الصفحة الرئيسية (مشغّل افتراضيًا) يضع شريطًا من بطاقات المجموعات فوق تدويناتك، على أيٍّ من نوعي الصفحة الرئيسية. فقائمة التدوينات للتصفح، والمجموعة للتنقل، ومكان التنقل فوق ما يتنقّل فيه. وتظهر المجموعة الفارغة هنا أيضًا: فالمجموعة التي أنشأتها ولم تملأها بعد دعوةٌ لا خطأ، وبطاقتها تقول «لا ملاحظات منشورة» على وجهها.
  • إظهارها في شريط التنقل (معطّل افتراضيًا) يضع شرائح المجموعات في صدر صف المواضيع، كلٌّ بعلامتها بدل #. وهي لا تنطوي أبدًا في «المزيد ▾» ولا في القائمة المطوية على الهاتف، لأن المجموعة المعلنة بنية الموقع نفسه. غير أن المجموعة الخالية لا تأخذ شريحة: فالشريط دعوة، أما الشريحة في التنقل فوعدٌ بمكان يُذهب إليه، وعلى الهاتف تأخذ تلك الشريحة خانةً تحتاجها المجموعات التي فيها تدوينات.

وكلّ صفحة مجموعة تعمل في الحالين، فالمفتاحان يخفيان الأبواب لا الغرف التي خلفها. تسرد كل صفحة تدويناتها تمامًا كما تفعل صفحة الموضوع، تحت ترويسة تحمل علامة المجموعة وعنوانها ووصفها وعددها. ويمكن إخفاء مجموعة بعينها من غير حذفها: تحتفظ بعنوانها وعلامتها وأعضائها، ولا يصل إليها زائر، وإظهارها يعيدها كاملة.

وتبقى صفحات المجموعات خارج خريطة الموقع للسبب نفسه الذي تبقى له صفحات المواضيع: فكلّ منها فهرس لعناوين تسردها الخريطة أصلًا.

وتصل المجموعات إلى الموقع المصمَّم أيضًا: يأخذها شريط تنقله حين يكون إظهارها في شريط التنقل مشغّلًا، وترصّها صفحته الرئيسية حين يكون إظهارها في الصفحة الرئيسية مشغّلًا.

معاينات التحويم

ضع المؤشر على أي رابط تدوينة (مدخل في القائمة، أو بطاقة في لوحة المعلومات، أو رابط ذي صلة أو سابق/تالٍ، أو نتيجة بحث) فيطفو مطلع تلك الملاحظة في بطاقة، معروضًا بالطريقة نفسها التي تُعرض بها صفحة المقالة. ويمكن تمرير البطاقة، فيستطيع القارئ أن يقرأ ما بعد المقتطف بكثير من غير أن يغادر الصفحة التي هو فيها. وقرب أسفل النافذة تنقلب لتقف فوق الرابط، وتبقى مكانها بينما ينتقل المؤشر إليها. تنفتح في المساحة المتاحة في النافذة، وتتلاشى عند الحافة التي خلفها نصّ أكثر، وتستجيب للوحة المفاتيح أيضًا: فالرابط الذي تصل إليه بـTab يأخذ البطاقة نفسها. أما أجهزة اللمس والقرّاء الذين طلبوا حركة أقل فلا بطاقة لهم. وتُجلب الملاحظة كما يجلبها الزائر تمامًا، فالملاحظة غير المنشورة لا شيء فيها يُعاين.

العودة إلى الأعلى

بعد أن يمرّر القارئ نحو شاشة كاملة إلى الأسفل تظهر علامة ✦ صغيرة في الزاوية السفلية عند نهاية السطر (اليمنى في الإنجليزية، واليسرى في العربية). تحمل القارئ إلى الأعلى ببريق ذهبي. وترفع نفسها عن طريق التذييل وصندوق التعليقات بدل أن تغطّيهما، وإذا كان prefers-reduced-motion مضبوطًا قفزت فورًا بلا بريق.

الصفحة الرئيسية بلوحة المعلومات

أتفضّل واجهة مجلة على الصفحة الرئيسية بأسلوب الملاحظة؟ اضبط الإعدادات ← النشر ← الوضع ← لوحة المعلومات. (مفتاح الإعدادات هو home.mode: "dashboard"؛ ويمكنك أيضًا أن تكتب { "home": { "mode": "dashboard" } } في ASTROLABE_DATA/settings.json أو ترسله عبر PATCH /api/settings، ويُلتقط التغيير مباشرة.) فتصير الصفحة الأولى /:

  • صدارة بكامل العرض (كتلة افتتاحية كبيرة في أعلى الصفحة): اسم الموقع (أو شعاره) وشعاره النصي فوق صورة غلاف (home.banner، رابط https أو مرفق من الخزانة؛ ومن دونها تدرّج لوني يُولَّد من اسم الموقع)؛
  • شبكة بطاقات لأحدث التدوينات، بعمود أو عمودين أو ثلاثة بحسب العرض، في كل بطاقة صورة غلاف مصغّرة (بالبديل المولَّد نفسه) ومقتطف وشرائح وسوم؛
  • وحين يكون القرّاء قد تحدثوا، صفًّا نحيلًا بعنوان «الأكثر نقاشًا» مرتّبًا بعدد التعليقات.

وبوصفك مديرًا افتح معاينة كزائر ومرّر المؤشر فوق الصدارة: يظهر زر «تغيير الغلاف…» ويفتح المنتقي المعتاد (الصق رابطًا، أو اختر مرفقًا من الخزانة، أو ارفع صورة). وhome.mode: "note"، أو ترك المفتاح من غير ضبط، يُبقي الصفحة الرئيسية التقليدية. ومع COMMENTS=on يحمل GET /api/posts عددَ commentCount لكل تدوينة، وعدد الزائر لا يشمل إلا التعليقات الظاهرة.

ويقرأ صفوف الصفحة الرئيسية التخطيطان blog وdesigned ولا شيء غيرهما. ففي التخطيط الافتراضي app لا تفعل شيئًا، وتقول لوحة الإعدادات ذلك على الصفوف نفسها وتعتّمها. والنسخة التي تعمل بتخطيط التطبيق تفتح ملاحظة الرئيسية في / ببساطة.

ما يحيط بالمقالة

مقالة مدونة بتعليقات

تنتهي كل مقالة بروابط مشاركة (يمكن إيقاف الصف من الإعدادات ← النشر)، وروابط التدوينتين السابقة والتالية، وقائمة «ذات صلة» (ملاحظات منشورة تشير إلى هذه أو تشير هذه إليها)، والتعليقات، ويتبعها، إن ردّت عليها مواقع أخرى أو أعجبت بها أو أشارت إليها ووافقتَ على ذلك، قسمٌ صغير اسمه الإشارات (إشارات الويب والفيديفيرس). ويحمل التذييل رابط RSS غير لافت ورابط تسجيل دخول وإشارة صغيرة «يعمل بأسطرلاب». ولإخفاء تلك الإشارة ضع .s-blog-powered { display: none } في ملفك custom.css.

RSS وخريطة الموقع وتحسين محركات البحث

أربعة أشياء موجّهة لبرامج الزحف وقارئات الخلاصات تأتي مع كل تخطيط. كلها تحترم PUBLIC=false، وكلها لا تذكر إلا الملاحظات المنشورة، فالعنوان غير المنشور يبدو تمامًا كعنوان لا وجود له.

  • RSS على /feed.xml: خلاصة RSS 2.0، يُعلَن عنها في كل صفحة بـ<link rel="alternate" type="application/rss+xml">. يشير كل عنصر فيها إلى عنوان الملاحظة نفسها ويحمل المقتطف وصفًا. و<pubDate> فيها تاريخ ميلادي بصيغة RFC-822 دائمًا، أيًّا كان إعداد تقويم التواريخ، لأنه صيغة تحلّلها قارئة الخلاصات، لا تاريخ يقرؤه إنسان.
  • خريطة الموقع على /sitemap.xml: urlset بمعيار sitemaps.org 0.9، تسرد الصفحة الأولى ثم كلّ ملاحظة منشورة يمكن للزائر أن يراها، الأحدث أولًا، ولكل منها <lastmod> مأخوذ من تاريخ الملاحظة نفسها (date أو created أو published من المقدمة، وإلا فوقت إنشاء الملف). وتُدرج الصفحات الثابتة (page: true) وإن كانت الخلاصة تتركها: فصفحة «حول» ليست مقالة، لكنها عنوان يقدّمه هذا الموقع. أما صفحات المواضيع والمجلدات العامة فلا تُدرج، لأن كلًّا منها فهرس لعناوين موجودة في الملف أصلًا. وتتوقف القائمة عند حدّ البروتوكول، 50,000 عنوان، محتفظةً بالأحدث، مع تعليق XML يقول ذلك إن بلغت خزانتك هذا الحدّ يومًا.
  • Robots على /robots.txt: Allow: / وDisallow: /api/ وسطر Sitemap: يشير إلى الخريطة أعلاه.
  • وسوم SEO: يحمل HTML الذي يرسله الخادم <title> وmeta description ووسوم Open Graph (og:type=article على صفحات الملاحظات) ووسم canonical. تأخذ صفحة الملاحظة عنوان الملاحظة ومقتطفها، وتأخذ كل صفحة أخرى وسوم الموقع العامة.

وإذا كان للتدوينة توأم لغوي باللغة الأخرى، حملت صفحتا المقالة معًا <link rel="alternate" hreflang="ar"> وhreflang="en" وhreflang="x-default" يشير إلى لغة الموقع نفسه، وحمل كل مدخل في خريطة الموقع صفوف <xhtml:link rel="alternate"> للوجهين. وهكذا يُخبَر محرك البحث أن العنوانين مقالة واحدة بلغتين لا نسخة مكررة من الأخرى. أما الاقتران الذي وجهاه بلغة واحدة فلا ينال شيئًا من ذلك — إذ لا شيء عن اللغة يُقال — ويسمّي كلٌّ منهما الآخر تحت عنوان المقالة بدلًا من ذلك.

وتُبنى العناوين المطلقة في الأربعة كلها من SITE_URL إن كان مضبوطًا، وإلا فمن ترويسات Host وX-Forwarded-* في الطلب.

وتقبل الخلاصة وخريطة الموقع كلتاهما ?lang=ar أو ?lang=en حين تكون التصفية حسب اللغة مشغّلة. فبرنامج الزحف وقارئة الخلاصات لا يستطيعان إرسال الترويسة التي تستخدمها صفحات التطبيق نفسه، ولذلك يكون لكل نصف من الموقع ثنائي اللغة عنوانه الخاص.

على نسخة PUBLIC=false تقف خريطة الموقع خلف تسجيل الدخول تمامًا كالخلاصة (401 من غير جلسة)، ويجيب robots.txt بـDisallow: / كلَّ من لم يسجّل دخوله. وهذا الأخير ليس 401 عمدًا: فـRFC 9309 §2.3.1.3 يقول إن على برنامج الزحف أن يفهم أي 4xx على robots.txt بمعنى «لا قواعد هنا، ازحف بحرية»، وهذا عكس ما تعنيه الخزانة الخاصة. وجواب Disallow: / لا يكشف شيئًا، لأن كل عنوان حقيقي ما زال يجيب بـ401 بنفسه؛ هو فقط يوقف الزحف قبل أن يبدأ.

حرّر هذه الصفحة على GitHub

أسطرلاب برنامج حر. هذه الصفحات مبنية من ملفات Markdown في مجلد docs بالمستودع.