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

الإعداد

كل مفتاح في ملف .env، ولوحة الإعدادات داخل التطبيق، وأيّهما يغلب حين يقول كلٌّ منهما شيئًا مختلفًا.


يُضبط أسطرلاب من مكانين، ويكاد المكانان يغطّيان الأمور نفسها.

  1. ملف .env. ملف نصيّ بسيط بجانب التطبيق، في كل سطر منه مفتاح وقيمته على هيئة KEY=value. يقرؤه الخادم مرةً واحدة عند تشغيله، فإذا غيّرت شيئًا فيه فلا بد أن تعيد تشغيل الخادم ليأخذ به.
  2. لوحة الإعدادات. وهي داخل التطبيق نفسه. حين تغيّر شيئًا فيها يكتبه الخادم في ملف اسمه settings.json داخل مجلد بياناته، ويسري التغيير فورًا، بلا إعادة تشغيل.

معظم الإعدادات موجودة في المكانين معًا. فإذا اختلفا غلبت لوحة الإعدادات: القيمة المحفوظة في اللوحة تتقدّم على القيمة نفسها في .env. وإذا مسحت الحقل من اللوحة عادت قيمة .env إلى العمل. وثمّة استثناء واحد: المفاتيح الحسّاسة أمنيًّا (كلمة المرور، وسرّ الجلسة، والمنفذ، ونحوها) تعيش في .env وحده، ولا تعرضها اللوحة ولا تغيّرها أبدًا.

تحديث خادم تشغّله بنفسك

يقرأ الخادم إصداره من package.json، ويحمل العميل الإصدار الذي بُني به. بعد git pull شغّل npm run build ثم أعد التشغيل: السحب يحرّك الإصدار، والبناء يحرّك الملفات. إذا بقي تبويب مفتوحًا بعد نشر جديد قال مرةً واحدة: أسطرلاب X صار على الخادم، أعد التحميل لتلحق به. وإذا أعادت إعادةُ التحميل النسخةَ القديمة نفسها — لأن الملفات لم يُعَد بناؤها، أو لأن عامل الخدمة ما زال يقدّم الواجهة القديمة — قال التطبيق ذلك بدلًا منها، مرةً لكل إصدار، وكفّ عن السؤال: يقول الخادم إنه أسطرلاب X لكنه يقدّم نسخة Y. ولهذا السطر معنى واحد: شغّل npm run build (أو أعد تثبيت الحزمة) على الجهاز الذي يشغّل الخادم. أما تطبيق الحاسوب وتطبيق أندرويد فيحملان بناءهما مع خادمهما، فلا يُظهرانه أبدًا.

متغيرات البيئة

متغيّر البيئة قيمة لها اسم، يقرؤها الخادم عند تشغيله. يمكنك أن تضعها في ملف .env، أو في سطر الأوامر (الطرفية) الذي تشغّل الخادم منه؛ وفي الحالين تصل إلى المكان نفسه.

سكربتات npm تحمّل ملف .env من تلقاء نفسها (عبر node --env-file-if-exists=.env)، فلست بحاجة إلى export ولا إلى source. أما ملف .env.example في جذر المستودع فيسرد كل المفاتيح مع تعليق يشرح كل واحد منها؛ والجدول التالي هو النسخة المختصرة.

المفتاحما هو
PORTالمنفذ الذي يستمع عليه الخادم (الافتراضي 6801)
HOSTالعنوان الذي يستمع عليه الخادم (الافتراضي 0.0.0.0، أي كل واجهات الشبكة). إذا استمع الخادم على غير الجهاز المحلي ولم تكن هناك كلمة مرور، طبع تحذيرًا صارخًا عند التشغيل: كل من يصل إلى المنفذ يصير مشرفًا
ASTROLABE_VAULTمجلد الخزانة، أي المجلد الذي يحوي ملاحظاتك (الافتراضي ./vault). والمعامل --vault <path> في سطر الأوامر يتقدّم عليه
ASTROLABE_DATAمجلد بيانات الخادم (الافتراضي ./data). فيه settings.json، وقاعدة بيانات التعليقات (SQLite)، وملفك custom.css، وdesigns.json، وملف اعتمادات git، ورمز القصّاصة (clip-token)، ومجلد fonts/ (ملفات خطوطك، مع نسخة الكتالوج المحفوظة في fonts/catalog/ والخطوط المرفوعة في fonts/custom/)، وversions/ (تاريخ الملاحظات)، وauthor-sites.json، والدفاتر الثلاثة التي هي لك لا للجهاز: layouts.json وbooks.json وannotations.json. وستة من هذه الملفات، وهي settings.json وdesigns.json وcustom.css وlayouts.json وbooks.json وannotations.json، ومعها مجلد fonts/، تُنسخ إلى <vault>/.astrolabe/، وهو مجلد نقطي لا يعرضه أوبسيديان أبدًا، فيبدأ منها خادم ثانٍ فوق الخزانة نفسها (انظر الإعدادات تسافر مع الخزانة)
ADMIN_PASSWORD_HASHكلمة مرور المشرف، مخزّنةً على هيئة تجزئة argon2id، أي بصمة يستطيع الخادم أن يتحقق بها من كلمة المرور ولا يمكن استرجاع كلمة المرور منها. يصنعها لك الأمر npm run hash-password. وإذا لم يُضبط هذا المفتاح عمل التطبيق في الوضع المحلي المفتوح: لا كلمة مرور، والكل مشرف
SESSION_SECRETنصّ طويل عشوائي يوقّع به الخادم ملفات تعريف الارتباط (الكوكيز) التي تثبت أنك سجّلت دخولك. وإذا لم يُضبط اخترع الخادم سرًّا جديدًا عند كل تشغيل، فيُخرجك كل إعادة تشغيل من حسابك
PUBLICالقيمة false تطلب تسجيل الدخول حتى للقراءة (الافتراضي: القراءة للجميع، والتحرير لمن سجّل دخوله). يرفض الخادم أن يبدأ إذا ضُبط PUBLIC=false من غير ADMIN_PASSWORD_HASH
SECURE_COOKIEStrue أو false لفرض علامة Secure على ملف الجلسة. وإذا لم يُضبط قرّر الخادم من الطلب نفسه: HTTPS يأخذ العلامة، وHTTP العادي لا يأخذها (ويمكن لوكيل موثوق أن يقول «هذا HTTPS» عبر الترويسة X-Forwarded-Proto)
TRUSTED_PROXIESعناوين IP، أو نطاقات عناوين بصيغة CIDR، مفصولة بفواصل، يُصدَّق ما تقوله ترويستاها X-Forwarded-For وX-Forwarded-Proto (مثل 127.0.0.1,::1). وإذا لم يُضبط تُتجاهل الترويستان، ويُحسب حدّ المحاولات على عنوان الاتصال نفسه
HOME_NOTEالملاحظة التي يهبط عليها الزائر أول مرة، مسارًا داخل الخزانة، مثل index.md
COMMENTSالقيمة on (وكذلك true و1 وyes) تسمح للقرّاء بترك تعليقات تحت الملاحظات المنشورة (الافتراضي: معطَّل)
NOTE_VERSIONSالقيمة off (وكذلك false و0 وno) توقف احتفاظ التطبيق بنسخة من كل ملاحظة قبل كل حفظ في ASTROLABE_DATA/versions/ (الافتراضي: مفعَّل)؛ انظر النسخ، قبل git وإلى جانبه
PDF_SEARCHالقيمة off (وكذلك false و0 وno) تمنع بحث الشريط الجانبي من قراءة نصوص ملفات PDF على رفّك (الافتراضي: مفعَّل؛ انظر البحث داخل كل كتاب)
SPEAK_EXTERNALالقيمة on (وكذلك true و1 وyes) تسمح للمدير بضبط المتحدّث الخارجي في القراءة بصوت عالٍ، وهو برنامج يشغّله الخادم بمستخدمه نفسه (الافتراضي: معطَّل، فلا يُحفظ أمر، ولا يُشغَّل أمر حُفظ من قبل). في ‎.env وحده — فهو قرار مشغّل الجهاز لا قرار من يملك كلمة مرور المدير. وتطبيق سطح المكتب مشغّلُ نفسه فيفعّله
OLLAMA_HOSTأين يجد اسأل الخزانة برنامج Ollama، وهو المتغير نفسه الذي يقرؤه Ollama (الافتراضي http://127.0.0.1:11434)
SITE_NAMEاسم الموقع، يظهر في الشريط الجانبي وعناوين الصفحات ونافذة تسجيل الدخول (الافتراضي Astrolabe)
SITE_TAGLINEسطر قصير تحت اسم الموقع، في وضع المدونة
SITE_FOOTERسطر التذييل في وضع المدونة. يُملأ فيه {year} و{siteName} تلقائيًّا (الافتراضي © {year} {siteName})
SITE_URLالعنوان العام للموقع، لروابط RSS والروابط القانونية، مثل https://notes.example.com. وإذا لم يُضبط استُنتج من كل طلب. في .env وحده؛ لا حقل له في اللوحة
LEGACY_HOSTSأسماء المضيفين القديمة التي كان الموقع يجيب عليها، مفصولةً بفواصل. الطلب الذي يصل على أحدها يُحوَّل تحويلًا دائمًا إلى المسار نفسه على SITE_URL، فتبقى الروابط القديمة تعمل بعد تغيير الاسم. يحتاج إلى SITE_URL؛ وفي .env وحده
DEFAULT_THEMEالسمة التي يراها الزائر قبل أن يختار واحدة: أيّ من السمات الست والأربعين المدمجة، أو custom:<name> لسمة بنيتَها أنت (انظر السمات)، أو follow. وتركه فارغًا يعني follow: يأخذ الزوار السمة التي تحرّر أنت فيها. لا فرق بين الحروف الكبيرة والصغيرة؛ والاسم المجهول يُتجاهل مع سطر واحد على stderr
EXCLUDE_TAGSوسوم مفصولة بفواصل تُخفى من قوائم المواضيع وحبوب الوسوم في الموقع العام، وهي عادةً وسوم سير العمل مثل draft,seedling. لا فرق بين الحروف الكبيرة والصغيرة، ولا بأس بعلامة # في أول الوسم. ولا يتأثر بها ما يراه المشرف نفسه
PUBLIC_LAYOUTما يراه الزائر: blog لتخطيط مدونة تقليدي (انظر وضع المدونة)، أو designed لصفحة رئيسية تركّبها بنفسك (انظر المصمم)، وأي قيمة أخرى تعني app، أي التطبيق للقراءة فقط (وهو الافتراضي)
SITE_LANGلغة الموقع: en (الافتراضي) أو ar. ومع ar تصير كل نصوص الواجهة عربية وتنعكس الواجهة كلها من اليمين إلى اليسار (انظر العربية والكتابة من اليمين). أما اللغة التي تحرّر أنت بها فاختيار مستقل، لكل متصفح على حدة: الإعدادات ← اللغة ← لغتك
BLOG_LOCALEرمز لغة ومنطقة (بصيغة BCP47، مثل ar-EG أو en-GB) يقرّر شكل الأرقام في تواريخ التدوينات ولغة خلاصة RSS (الافتراضي: يتبع SITE_LANG). وتتبع أسماءُ الشهور لغةَ الواجهة حين يكون مبدّل لغة الزائر مفعَّلًا
LANGUAGE_FILTERأي الملاحظات المنشورة يعرضها الموقع العام، بحسب اللغة المكتوبة بها: off (الافتراضي: اعرض الكل) · follow (كل قارئ يرى لغته) · ar · en. والقيمتان القديمتان true وfalse ما زالتا تعملان؛ انظر مرشّح اللغة
ATTACHMENTS_DIRمجلد الخزانة الذي تُحفظ فيه الملفات المرفوعة من داخل التطبيق (الافتراضي Attachments، أو مرفقات في الموقع العربي؛ ومجلد attachments الموجود أصلًا يبقى على حاله). يُنشأ عند أول حاجة إليه. ويستطيع إعداد المرفقات أن يرسل المرفوعات إلى مكان آخر تمامًا؛ انظر المرفقات
BANNER_FALLBACKصورة الترويسة لتدوينات المدونة التي ليس لها banner: خاص بها: generated (الافتراضي: تدرّج لوني تجريدي يُصنع من عنوان الملاحظة، ويظل هو نفسه للعنوان نفسه) أو none
ASTROLABE_GIT_SSH_COMMANDالمتغيّر الوحيد من عائلة GIT_* الذي يمرّره أسطرلاب إلى git كما هو، باسم GIT_SSH_COMMAND؛ انظر النسخ الاحتياطي والمزامنة

إن كنت ثبّتّه حين كان اسمه Vellum. كل مفتاح أعلاه ما زال يجيب بتهجئته القديمة: يُقرأ VELLUM_VAULT وVELLUM_DATA وسائرها حين لا يكون مفتاح ASTROLABE_* مضبوطًا، فيظل ملف .env أو وحدة systemd أو اختصار الصدفة الذي كُتب قبل إعادة التسمية يعمل. وحين يُضبط الاثنان تغلب التهجئة الجديدة، ويسمّي سطر التشغيل المفاتيح القديمة التي اعتمد عليها، مرة واحدة. وما زال /vellum.sty يُقدَّم بجانب /astrolabe.sty للأوراق المكتوبة على اسم الحزمة القديم.

حدود حجم الطلبات. لكل طلب يصل إلى الخادم حدٌّ أقصى للحجم، يُفرض قبل أن يقرأه أي شيء، ولا مفتاح له: 10 ميغابايت على أي طلب إلى /api، وحدّ أضيق كثيرًا هو 64 كيلوبايت على الشيئين اللذين يستطيع الزائر المجهول إرسالهما (التعليقات ومحاولات تسجيل الدخول). وكل ما يتجاوز الحدّ يُرفض برمز الخطأ HTTP 413 (أي «الطلب أكبر من المسموح») بدل أن يشغل الذاكرة. وللملفات المرفوعة حصّتها المستقلة. وإذا كان التطبيق خلف وكيل فإن حدًّا مماثلًا عند الوكيل طبقةُ حماية إضافية معقولة؛ في nginx مثلًا: client_max_body_size 10m;، أو 256m إن كنت ستُسقط أفلامًا في ملاحظاتك، لأن لرفع الفيديو حصّته الخاصة: 256 ميغابايت.

لوحة الإعدادات

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

صف واحد، وشكل واحد. كل صف عنوانٌ، وسطر مساعدة واحد تحته، وأداة واحدة في عمود واحد على اليسار (وعلى اليمين في الإنجليزية): مفتاح، أو مجموعة أزرار، أو قائمة، أو صفّ من الشرائح المسمّاة، أو منزلق قيمته في العنوان (دفء الشاشة · 30%)، أو حقل مسار فيه اختر…، أو حقل نص، أو — للصفوف القليلة التي هي جداول — عرض الصف كله. ولا يُكتب بجانب المفتاح «مفعل» أو «معطل»: العنوان يقول ما يعنيه التشغيل. وتفتح ⓘ بجانب العنوان فقرةً تحت الصف تقول لماذا قد تغيّره، ومتغيّر البيئة حين يكون وراءه، جاهزًا للنسخ.

محفوظ، أو مُبقًى هنا. الصف المحفوظ في هذا المتصفح يحفظ نفسه لحظة تختار. والصفحة المكوّنة كلها من هذه الصفوف (المظهر، وهذا الجهاز) تقول ذلك مرة واحدة تحت جملتها؛ وفي غيرها تحمل الصفوف القليلة التي هي كذلك وسمًا صغيرًا هذا الجهاز. وكل صف آخر هو للموقع، ويرتفع شريط حفظ أسفل اللوحة حالما يتغير أحدها (ومعه تجاهل)، ويختفي حين تحفظ.

أنت

  • المظهر: سمتك ومنزلقا راحة العين (انظر السمات)، وعلى أي حافة تجلس لوحة الملاحظات، وعرض عمود الكتابة. وكلها محفوظة على هذا الجهاز.
  • التخطيط والخط: اتجاه نص الملاحظات ومحاذاته، وتستطيع أي ملاحظة تجاوزهما من مقدمتها (انظر اتجاه الملاحظة ومحاذاتها)، وخانات الخطوط الأربع (نص القراءة / الواجهة / الكود / الوجه العربي) من فهرس مختار مستضاف ذاتيًا أو من خطوط ترفعها بنفسك، مع عيّنة حية تبقى على الشاشة وأنت تختار (انظر الطباعة).
  • اللغة: لغتك (تبعًا للموقع / English / العربية: كلمات التطبيق لك على هذا الجهاز، وليست أبدًا ما يأخذه الزوار) بجانب لغة الموقع (ما يقرأ به الزوار)؛ والتدقيق الإملائي في: صفّ واحد من الشرائح يسمّي اللغات التي تُسلَّم أسطرها إلى المدقّق الإملائي، ففي المتصفح اللغاتُ الأربع التي يعرفها المحرر، ولا شيء منها حتى تختار، وفي تطبيق سطح المكتب القواميس الموجودة فعلًا على حاسوبك (انظر المحرر)؛ وللزوار: مرشح اللغة ومفتاح الزائر الاختياري.
  • التواريخ والتقويم: تقويم التاريخ (ميلادي / هجري / كلاهما، مع نموذج حي لليوم، ومع كلاهما أيهما يتقدّم والعلامة بينهما؛ انظر التواريخ الهجرية)؛ وتحت متقدّم: لغة التواريخ.
  • الكتابة: افتح عند التشغيل (على ماذا يفتح التطبيق: حيث توقفت، أو صفحة السِّجِلّ، أو رفّ المدارات، أو ملاحظة اليوم، أو ملاحظة تختارها؛ فوق الجلسة المستعادة، ولا يفتح أبدًا فوق رابط ملصوق)، وشريط التنسيق، وتصحيح الفرنسية تلقائيًا، وبطاقة الخصائص (إيقافها يخفيها عمّا تراه أنت — ويبقى الزوار يرونها؛ انظر المحرر) ومعها بطاقة الملاحظة الفارغة؛ وأين تُكتب المرفقات الجديدة (انظر المرفقات)، ومجلد الوسوم، وجدول تسميات الوسوم: أسماء عرض للوسوم الأصلية، لواجهة ينبغي أن تقرأ «برمجيات» فوق خزانة تحتفظ بـ#software (انظر تسميات الوسوم المحلية)؛ وتحت متقدّم: مجلد الرسوم.
  • الملاحظات الجديدة والقوالب: مجلد القوالب وقالب الملاحظات الجديدة، والملاحظات الدورية (جدول واحد: المجلد الذي تتشاركه الأنواع الأربعة، واسمٌ وقالبٌ لكلٍّ من اليوم والأسبوع والشهر والسنة)، ومجلد الملاحظة الفريدة واسمها، وصندوق الالتقاط والقصّاصة.
  • القراءة: ترقيم العناوين في عرض القراءة، والبحث داخل الكتب (البحث في PDF)، والخلاصات مع الملاحظة التي تسردها؛ وتحت متقدّم: مجلد الأحاديث (الملاحظات التي تجيب تنبيهات > [!hadith]؛ انظر تنبيهات الآية والحديث).
  • القراءة بصوت عالٍ والملاحظات الصوتية: القراءة بصوت عالٍ وهل يستمع قرّاء مدونتك؛ ولغة تفريغ الملاحظات الصوتية، والنموذج وأين يعمل، وهل تُحفظ التسجيلات (انظر الالتقاط)؛ وتحت متقدّم: أصواتك الخاصة.

موقعك

  • هوية الموقع: الاسم، والعنوان الفرعي، وصورة شعار (تحل محل الاسم النصي في الشريط الجانبي وترويسة المدونة)، وأيقونة (تُقدَّم على ‎/favicon.ico بنوع محتواها الحقيقي وتُحقن في <link rel="icon"> في كل صفحة)، والسمة الافتراضية التي يصل إليها الزوار، وأجواء الترويسة؛ وتحت متقدّم: سطر التذييل.
  • النشر: كم من الموقع عام، بالأرقام في أعلى الصفحة؛ والتخطيط العام (app / blog / designed، وتحته باب المصمّم)؛ والصفحة الرئيسية: وضع note الكلاسيكي بملاحظة رئيسية تختارها، أو تخطيط المجلة dashboard، مع لافتة اختيارية (لا يقرؤها إلا تخطيطا blog وdesigned، فمع التخطيط العام: app تبهت الصفحة هذه الصفوف وتقول ذلك)؛ وأزرار المشاركة والفيديو الخارجي؛ وتحت متقدّم: الوسوم المستبعدة ومواقعك الأخرى.
  • التعليقات والإشارات: التعليقات، وإشارات الويب والفيديفيرس، كلٌّ منها معطّل حتى تشغّله.
  • المجموعات: هل تأتي الفئات من الوسوم أم من المجلدات، ومجموعاتك المصنوعة بيدك وأين تجلس. انظر وضع المدونة.
  • المكتبة: الرفّ العام: تشغيله أو إيقافه، واسمه، وأين بابه، وأي المجلدات تملؤه والاستثناءات. انظر المكتبة.

البيانات

  • النسخ الاحتياطي والمزامنة: أودع الخزانة وادفعها إلى مستودع git خاص تملكه، يدويًا أو على مؤقت (معطّل حتى تشغّله)؛ وتحت متقدّم: الفرع والسحب أولًا. انظر النسخ الاحتياطي والمزامنة.
  • النسخ السابقة والتنقّل: نسخة من كل ملاحظة قبل كل حفظ؛ وما يحمله مجلد .astrolabe/ في الخزانة إلى الجهاز التالي؛ وهل تنتقل تفضيلات هذا المتصفح معها.
  • اسأل: أي النماذج تقرأ الملاحظات وتجيب عنها، ونموذج التضمين وعدد المقاطع لكل إجابة تحت متقدّم. انظر اسأل الخزانة.

التطبيق

  • هذا الجهاز: النسخة دون اتصال مما تفتحه، ومفاتيح Vim (مع أرقام الأسطر النسبية)، وعرض «ما الجديد» بعد التحديث، وفي تطبيق سطح المكتب وحده اسمه وأيقونته ومدخل المشغّل وتحديثات البرنامج (انظر تطبيق سطح المكتب). وكلها محفوظة على هذا الجهاز.
  • حول: الإصدار، وإصدار Node، وأعداد الخزانة، والمسارات المطلقة للخزانة ومجلد البيانات وsettings.json ومجلد الخطوط المرفوعة.

وخزانة الجيب (مستودع GitHub مفتوح في تطبيق أندرويد) تعرض أربع عشرة صفحة: فالنشر والتعليقات والإشارات والمجموعات والمكتبة واسأل تحتاج خادمًا، والصفوف التي لا تستطيع حفظها تُرسم باهتة، مع سطر واحد يقول لماذا.

حقول الصور تعيد استخدام آلية اللافتات: اختر من مرفقات الخزانة أو ارفع هناك مباشرة (سحب وإسقاط؛ تُشمّ البايتات؛ وتحطّ حيث يشير إعداد المرفقات).

المرفقات

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

الوضعيحطّ الرفع في
جذر الخزانةأعلى الخزانة
المجلد نفسه للملاحظةبجانب الملاحظة التي تُحرَّر
مجلد فرعي من مجلد الملاحظة<مجلد الملاحظة>/<الاسم>، مثل assets بجانب كل ملاحظة
مجلد محدد (الافتراضي)مجلد ثابت واحد نسبي إلى الخزانة: ATTACHMENTS_DIR، وإلا مرفقات (وAttachments في النسخة الإنجليزية)؛ والخزانة التي فيها مجلد attachments أصلًا تبقى عليه

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

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

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

أي ملف يمكن أن تحويه الخزانة، لا الصور وحدها. يقبل POST /api/upload الصور (png وjpeg وwebp وgif وsvg وavif وheic وbmp)، وملفات PDF، والصوت (mp3 وm4a وwav وogg وoga وopus وflac)، والفيديو (mp4 وm4v وmov وwebm وmkv وogv). يصل الفيلم إلى 256 ميغابايت ويُكتب على القرص وهو يصل، وسائر الملفات بحدّ 10 ميغابايت لكل ملف. ويُفحص محتوى الملف، فالبرنامج الذي أُعيدت تسميته إلى .png يُرفض مهما ادّعى امتداده. وكل ما ليس في تلك القائمة يُرفض في المتصفح، قبل أن يبدأ الرفع، برسالة تسمّي ما رُفض وما كان سيُقبل.

أسقط الملفات في أي مكان على الشجرة. اسحب ملفات من مدير الملفات إلى مجلد في الشريط الجانبي (أو إلى ملاحظة، فتحطّ بجانبها) فتُضاف إلى الخزانة. يضيء الصف ويقول كم ملفًا في الطريق. وبعدها يسمّي تنبيهٌ المجلدَ الذي حطّت فيه فعلًا ويعرض تراجعًا ينقلها إلى .trash/. وإذا كان الاسم مشغولًا أخذ الملف الجديد أول اسم حرّ على هيئة name-2.ext، وقال التنبيه ذلك.

والحذف يخبرك بما يأخذه حقًّا. تعرض شجرة الشريط الجانبي الملاحظات فقط. لذلك كان المجلد الذي بقيت فيه أربع صور بعد أن غادرته ملاحظته يصف نفسه بـ«0 ملاحظات»، وكان حذفه يكسر مقالةً منشورة في صمت. أما الآن فكل تأكيد حذف يسأل الخادم عمّا في الداخل فعلًا:

نقل "Media" إلى .trash؟ 0 ملاحظات، 60 مرفقًا، 53 منها تشير إليها 48 ملاحظة. ينتقل كل ذلك إلى مجلد .trash في الخزانة، قابلًا للاسترداد من القرص.

وحين تكون الملاحظات التي تشير إلى الملفات قليلة تُذكر بأسمائها. ولا تُحسب كسرًا إلا الملاحظات التي تنجو من الحذف؛ فالملاحظة التي تذهب في الحذف نفسه ليست رابطًا مكسورًا. ويُحسب نوعا الروابط معًا، تضمينات الويكي (![[fig.png]]) وروابط ماركداون (![](assets/fig.png))، ومعهما banner: الملاحظة. ويكرّر تأكيدُ الحذف النهائي الجردَ نفسه، وحذف مرفق واحد (علامة × على صف في قائمة منتقي اللافتة) يسأل السؤال نفسه.

وكل عنصر تحكّم في اللوحة يرسمه أسطرلاب، لا نظام التشغيل. فالقائمة المنسدلة نافذة منبثقة بسمة التطبيق، معلّقة بزرّها ومحفوظة داخل اللوحة: لا يزيد ارتفاعها على المساحة المتاحة، وتنقلب إلى الأعلى حين لا مكان تحتها، وتستجيب لمفاتيح الأسهم وللكتابة (اكتب أول الاسم فتقفز إليه)، وEnter يثبّت وEsc يعيد القيمة القديمة. ومفاتيح التشغيل والإيقاف مفاتيح حقيقية تُقلب بنقرة؛ والصفوف الثلاثية (وراثة / تشغيل / إيقاف) تعرض حالاتها الثلاث معًا؛ والأرقام تحمل وحدتها داخل الحقل. والسبب أن عنصر <select> الأصلي يفتح نافذة يرسمها نظام التشغيل، لا تصل إليها سمة ولا تحتويها لوحة، وهذا بالضبط ما يجب ألا تفعله قائمة خطوط من سبعة وعشرين وجهًا.

على الهاتف (تخطيط الهاتف) اللوحة قائمة بالأقسام التسعة نفسها، بالترتيب نفسه وبالأسماء نفسها — المزيد ← الإعدادات — وفوقها البحث نفسه، وكل قسم شاشة مستقلة فيها الصفوف نفسها. وحالما يحمل القسم تغييرًا يصعد شريط من الأسفل فيه تجاهل وحفظ؛ ومغادرة القسم بأي طريق آخر وفيه تغييرات لم تُحفظ تسأل أولًا. أما الصف الموسوم هذا الجهاز فيحفظ نفسه حين تختار، ولا يرفع الشريط أبدًا.

مفاتيح الإعدادات

هذه هي المفاتيح التي يمكن أن يحملها ASTROLABE_DATA/settings.json. تكتبها اللوحة، ويكتبها كذلك PATCH /api/settings. وكل مفتاح غائب يعود إلى قيمته الافتراضية من .env في الجدول أعلاه.

المفتاحالقيمالافتراضي
siteNameنص، ≤ 80 حرفًاSITE_NAME، وإلا Astrolabe
taglineنص، ≤ 160SITE_TAGLINE، وإلا لا شيء
footerنص، ≤ 200SITE_FOOTER، وإلا © {year} {siteName}
defaultThemeأحد المعرّفات الست والأربعين، أو custom:<name> لسمة موجودة، أو follow (يتبع الزوار سمة محررك)DEFAULT_THEME، وإلا follow
adminThemeمعرّف سمة واحد، يكتبه التطبيق لا اليد: سمة محررك أنت، تُنسخ من متصفحك ليجد follow ما يقدّمهلا شيء حتى تختار سمة
publicLayoutapp · blog · designedPUBLIC_LAYOUT، وإلا app
blogLocaleرمز لغة ومنطقة (BCP47)، ≤ 35 حرفًا، يُوحَّد شكله عند الحفظBLOG_LOCALE، وإلا ar حين تكون اللغة عربية، وإلا en
languageen · arSITE_LANG، وإلا en
languageFilteroff · follow · ar · enLANGUAGE_FILTER، وإلا off
languageToggleمنطقي: مبدّل EN/ع العام. لا نظير له في البيئةfalse
topicstags · folders: من أين تأتي فئات الموقع العام (الإعدادات ← المجموعات)tags
excludeTagsمصفوفة نصوص، ≤ 200 مدخل، ≤ 50 حرفًا لكل منهاEXCLUDE_TAGS، وإلا فارغة
commentsEnabledمنطقيCOMMENTS، وإلا false
noteVersionsمنطقي: الاحتفاظ بنسخة من كل ملاحظة قبل كل حفظ (الإعدادات ← النسخ الاحتياطي والمزامنة)NOTE_VERSIONS، وإلا true
shareButtonsمنطقي: صف المشاركة تحت مقالات المدونةtrue
authorSitesمصفوفة { url } (https)، يجلب الخادم عنوان كل موقع منها وصورته مرة واحدة (من بطاقة OpenGraph الخاصة به) ويحفظهما في ASTROLABE_DATA/author-sites.json؛ تُعرض على المدونة بطاقاتٍ تحت المزيد من الكاتب. لا نظير له في البيئةفارغة
ambientمنطقي: حركة زخرفية بطيئة خلف ترويسة الموقع العام، مرسومة لكل سمة على حدة (انظر السمات)false
pdfSearchمنطقي: يقرأ بحث الشريط الجانبي صفحات كل ملف PDF على الرف (انظر البحث داخل كل كتاب)PDF_SEARCH، وإلا true
externalVideoمنطقي: رابط YouTube أو Vimeo أو PeerTube في سطر مستقل يعمل في مكانه، في التطبيق وعلى المدونة (الإعدادات ← النشر ← تضمين الفيديو الخارجي؛ انظر التضمين). لا نظير له في البيئةfalse
feeds{ fetch, note }: الخلاصات: هل يجوز للخادم أن يجلب الخلاصات التي تتابعها (الإعدادات ← القراءة ← الخلاصات)، والملاحظة التي تسردهاfetch: false، وnote: Feeds.md
voice{ model, backend, language, keepAudio }: الملاحظات الصوتية: نموذج التفريغ (base-q5_1 · small-q5_1 · large-v3-turbo-q5_0 · large-v3-turbo · off)، وأين يعمل (auto · cpu أي المعالج وحده)، واللغة (auto · ar · en)، وهل يُحتفظ بالتسجيلsmall-q5_1، auto، auto، true
speak{ engine, rate, voices, public }: القراءة بصوت عالٍ: المحرّك (light · natural)، والسرعة (0.8 · 1 · 1.2)، والصوت المختار لكل لغة، وهل يستمع قرّاء المدونة. ويُقبل هنا مفتاحان فرعيان آخران، voicesDir (مجلد أصواتك الخاصة) وexternal ({ command, langs }، المتحدّث الخارجي)، لكنهما يُكتبان في ASTROLABE_DATA/speak-local.json لا في settings.json أبدًا: فهما يسمّيان مسارات هذا الجهاز وبرامجه، ولا يسافرانlight، 1، أول صوت في كل محرّك، false
webmentions{ accept, send }: إشارات الويب: استقبالها إلى المراجعة، وإخبار المواقع التي تربط إليها التدوينة حين تُنشر (الإعدادات ← التعليقات والإشارات ← إشارات الويب). لا نظير له في البيئةكلاهما false
fediverse{ enabled, handle }: المدونة حسابًا واحدًا في الفيديفيرس، والاسم الذي قبل @ (من 1 إلى 30 حرفًا أو رقمًا أو شرطة سفلية). لا نظير له في البيئةenabled: false؛ والاسم هو اسم الموقع مطويًّا إلى تلك الحروف، وإلا blog
ask{ provider, chatModel, anthropicModel, embedModel, topK }: اسأل الخزانة: من يجيب (ollama · anthropic)، وأسماء النماذج، وعدد المقاطع التي تقرؤها الإجابة (2–12). ومفتاح Anthropic ليس هنا: فهو للكتابة فقط ويعيش في ASTROLABE_DATA/ask-credentials.json الذي لا ينتقل أبدًاollama وqwen3.5:9b وclaude-sonnet-5 وembeddinggemma و6
faviconصورة نسبية إلى الخزانة (.ico .png .svg .jpg .jpeg .gif .webp .avif)لا شيء
logoرابط https أو صورة نسبية إلى الخزانةلا شيء
home.modenote · dashboardnote
home.noteملاحظة نسبية إلى الخزانة (.md / .tex / .latex)HOME_NOTE
home.bannerرابط https أو صورة من الخزانةلا شيء: تدرّج مولَّد من اسم الموقع
publicFolders{ enabled, nav, home, folders[] }: المجموعات المصنوعة بيدك: هل هي مشغّلة، وباب في شريط التنقل، وشريط في الصفحة الرئيسية، وحتى 12 مجلدًا، لكل منها slug (≤ 60) وtitle (≤ 60) وdescription (≤ 200) وعلامة وراية hidden اختياريةمعطّل؛ home: true
library{ enabled, nav, home, title, paths[] }: المكتبة: مشغّلة أم لا، وباب في شريط التنقل (مشغّل افتراضيًا متى شُغّلت المكتبة)، ورفّ في الصفحة الرئيسية، واسم (≤ 40)، وحتى 24 مسارًا، كلٌّ منها مجلد في الخزانة له title (≤ 80) وblurb (≤ 300) ونوعمعطّل
attachments.modevault-root · same-folder · subfolder · specifiedspecified
attachments.folderمجلد نسبي إلى الخزانة، ≤ 180 حرفًا؛ يقرؤه الوضعان subfolder وspecified فقط. لا صعود خارج الخزانة، ولا مسار مطلق، ولا مجلد نقطةATTACHMENTS_DIR، وإلا مجلد موجود باسم attachments أو Attachments أو مرفقات، وإلا مرفقات (وAttachments في النسخة الإنجليزية)
templatesFolderمجلد نسبي إلى الخزانةيُكتشف تلقائيًّا (Templates أو _templates أو قوالب)، وإلا لا شيء
hadithFolderمجلد نسبي إلى الخزانة تجيب ملاحظاته (التي تحمل collection: وnumber: في مقدمتها) تنبيهات > [!hadith]يُكتشف تلقائيًا (hadith، Corpus/hadith، أحاديث)، وإلا فلا شيء
drawingsFolderمجلد نسبي إلى الخزانة يبدأ فيه قلم الشريط الجانبي رسمةً جديدةلا شيء: جذر الخزانة
defaultTemplateملاحظة نسبية إلى الخزانة تُطبَّق على كل ملاحظة جديدةلا شيء
dailyFolderمجلد نسبي إلى الخزانة تسكنه الملاحظات الدورية؛ "" لجذر الخزانةdaily
dailyFormatصيغة فترة تسمّي السنة والشهر واليوم (YYYY وMM وDD و[نص حرفي] و/)YYYY-MM-DD
weeklyFormatصيغة فترة تسمّي السنة وأسبوع ISO (ww)؛ "" يوقف الملاحظات الأسبوعيةYYYY-[W]ww
monthlyFormatصيغة فترة تسمّي السنة والشهر ولا شيء أدق؛ "" يوقف الملاحظات الشهريةYYYY-MM
yearlyFormatصيغة فترة تسمّي السنة ولا شيء أدق؛ "" يوقف الملاحظات السنويةYYYY
dailyTemplate / weeklyTemplate / monthlyTemplate / yearlyTemplateملاحظة نسبية إلى الخزانة تُطبَّق عند إنشاء ملاحظة تلك الفترةلا شيء (ويعود اليوم إلى defaultTemplate)
launchresume · sigils · orbits · today · ملاحظة نسبية إلى الخزانة: على ماذا تفتح واجهة المشرف فوق الجلسة المستعادة (انظر الملاحظات الدورية). لا نظير له في البيئةresume
uniqueFolderمجلد نسبي إلى الخزانة يودع فيه أمر ملاحظة فريدة جديدة ملاحظاته (انظر الملاحظات الفريدة)لا شيء — جذر الخزانة
uniqueFormatاسم الملاحظة الفريدة: رموز اليوميات ومعها HH وmm وss؛ يجب أن يذكر السنة وشيئًا أدق من اليومYYYYMMDDHHmm
captureInboxملاحظة نسبية إلى الخزانة تستطيع ورقة الالتقاط السريع أن تضع فيها السطور بدل ملاحظة اليوملا شيء؛ ملاحظة اليوم وحدها
dateCalendargregorian · hijri · bothgregorian
dateOrderauto · hijri-first · gregorian-first: أي التقويمين يتقدّم في bothauto (بحسب لغة الموقع)
dateSeparatorbar · dot · parens: ما يفصل بين التاريخين في bothbar
textDirectionauto · ltr · rtlauto
emptyPropsCardtrue · false: بطاقة الخصائص ذات السطر الواحد في الملاحظات التي لا مقدمة لهاtrue
propsCardtrue · false: بطاقة الخصائص أصلًا، في محرر المالك وعرض القراءة عنده (والزوار يرونها دائمًا)true
textAlignstart · left · right · center · justifystart
tagsFolderمجلد نسبي إلى الخزانة يحمل صفحات الوسوميُكتشف تلقائيًّا، وإلا tags
tagLabels{ tag: { en, ar } }، ≤ 200 وسم، يُستبدل كله ولا يُدمجفارغ
folderIcons{ \"folder/path\": \"mark\" }، ≤ 200 مجلد: علامات المجلدات التي ترسمها الشجرة؛ والعلامة التي ليست في الكتالوج تُهملفارغ
fonts.prose / .ui / .mono / .arabicمعرّف من الكتالوج، أو custom:<file> لخط مرفوع، أو systemsystem
fonts.arabicSizeAdjustنسبة مئوية صحيحة، 50–300القيمة المقيسة لخط الكتالوج نفسه، أو لا شيء
gitSync.enabledمنطقيfalse
gitSync.remotehttps://… أو ssh://… أو git@host:path، بلا اعتمادات مضمّنةلا شيء
gitSync.branchنصmain
gitSync.intervalMinutesعدد صحيح 0–1440؛ و0 تعني يدويًّا فقط0
gitSync.pullFirstمنطقي: سحب ما على المستودع البعيد قبل كل مزامنة، ولا يُقبل إلا إن كان مجرّد إضافة فوق ما عندك (التقديم السريع)true
gitSync.authModessh · tokenssh

وثمّة مفتاحان آخران للكتابة فقط: gitToken وgitUser. يقبلهما PATCH /api/settings ويخزّنهما في ASTROLABE_DATA/git-credentials.json، ولا يقرأ هذا الملف إلا مستخدم النظام الذي يعمل به الخادم (بالصلاحيات 0600). لا يدخلان settings.json أبدًا، ولا يمكن قراءتهما بعد ذلك: القراءة تجيب بـgitSync.tokenSet: true وباسم المستخدم، لا أكثر.

ويُكتب settings.json كتابةً ذرّية، أي أن الملف إما قديم بأكمله وإما جديد بأكمله، ولا يستطيع انهيار في المنتصف أن يتركه نصف مكتوب. والتغييرات تسري حيّة: اسم الموقع، والتخطيط، والسمة الافتراضية، والوسوم المستبعدة، ومسارات التعليقات، وأيقونة الموقع، كلها تتحدّث بلا إعادة تشغيل. وإذا فسد الملف يومًا سجّل الخادم تحذيرًا واحدًا وعمل على افتراضيات .env.

أما المفاتيح الحسّاسة أمنيًّا فهي عمدًا في .env وحده، وإلى الأبد. لا تستطيع اللوحة ولا /api/settings قراءتها ولا كتابتها: ADMIN_PASSWORD_HASH وSESSION_SECRET وTRUSTED_PROXIES وPORT وHOST وASTROLABE_VAULT وASTROLABE_DATA وPUBLIC. وSITE_URL في .env وحده أيضًا، لسبب أبسط: لم يحتج شيء قطّ إلى تغييره والخادم يعمل.

واجهة الإعدادات البرمجية

للسكربتات. وهي للمشرف وحده؛ يأخذ الزائر 404.

  • GET /api/settings يعيد المفاتيح المخزّنة، ومعها effective (القيم المدمجة المستخدمة فعلًا)، وكتالوج الخطوط، وكتلة about (الإصدار، وإصدار Node، والمسارات الكاملة، والأعداد).
  • PATCH /api/settings يأخذ كائنًا جزئيًّا. لا يتغيّر إلا المفاتيح التي تسمّيها؛ وnull تمسح مفتاحًا فيعود إلى .env. والتحقق صارم، فالمفتاح المجهول يُجاب بـ400، والجواب بالشكل نفسه الذي يعيده GET. أما مفاتيح اعتمادات git فتشترط فوق ذلك أن تكون للنسخة كلمة مرور حقيقية.

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

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