هل أنت مهتم بتصميم ثيمك الخاص لمنصة Discourse؟ لقد وصلت إلى المكان الصحيح ![]()
ستركّز هذه الدليل بشكل أكبر على جوانب SCSS/CSS في العمل مع الثيمات في Discourse. إذا كنت أيضًا على دراية بـ JS/EmberJs/Handlebars، فيمكنك الغوص في التفاصيل بشكل أعمق من خلال الاطلاع على هذا الدليل.
سأصف لك أسلوبي الشخصي في التصميم وإضفاء الطابع على Discourse. وكما هو الحال مع معظم الأمور، هناك طرق كثيرة لتنفيذ تصاميمك الخاصة. أستمتع باستخدام أدوات الفاحص (Inspector) بكثافة عند إنشاء الثيمات، وسأريك في هذا المنشور عدة مرات كيف أقوم بذلك.
الإعداد للبدء في التصميم
يرجى قراءة دليل المبتدئين لاستخدام ثيمات Discourse، وكذلك هيكلية الثيمات… قبل المتابعة. لا يلزم امتلاك معرفة عميقة في هذه المرحلة، لكن هذه المقالات ستمنحك بعض الألفة قبل البدء.
للعمل بأفضل طريقة مع التصميم في Discourse، أقترح عليك الإعداد بما يلي للحصول على أسرع عملية تصميم وأكثرها سلاسة. ستتيح لك هذه الخطوات رؤية تغييراتك أثناء إجرائها، دون الحاجة إلى “حفظ” وتحديث من لوحة إدارة موقع discourse.
من الممكن تمامًا العمل من خلال هذا الدليل باستخدام وحدة التحكم الإدارية (بشرط أن يكون لديك صلاحيات إدارية على منتدى discourse.)
- قم بتثبيت Discourse Theme CLI واقرأ الموضوع لفهم ما يمكنه فعله.
- احصل على مفتاح API من https://discourse.theme-creator.io/
- سجّل الدخول بحساب Meta الخاص بك
- انقر على ثيماتي
- انقر على مفتاح API
- في النافذة المنبثقة، انقر على إنشاء مفتاح API وانسخ المفتاح المُنشأ لك (سنستخدمه بعد قليل)
تشغيل Discourse Theme CLI
مع تثبيت Discourse Theme CLI، وجاهزية مفتاح API الخاص بك، افتح محرر النصوص المفضل لديك أو نافذة الطرفية (Terminal) وغيّر المجلد الحالي إلى المكان الذي تريد فيه إنشاء مجلد الثيم.
بمجرد الوصول إلى هناك، نفّذ الأمر التالي discourse_theme new your_theme_name واملأ الأسئلة المطروحة كما يلي:
-
ما الاسم الذي تريد منحه لثيمك؟ اختر اسم الثيم
-
هل تريد بدء مراقبة هذا الثيم؟ نعم
-
ما هو الرابط الجذري (Root URL) لموقع Discourse الخاص بك؟
https://discourse.theme-creator.io/ -
هل تريد حفظ اسم هذا الموقع في…؟ نعم
-
ما هو مفتاح API الخاص بك؟ أدخل مفتاح API الذي حصلت عليه من theme creator
-
هل تريد حفظ مفتاح API هذا في…؟ نعم
-
اختر إنشاء ومزامنة مع ثيم جديد عند الطلب
-
اختر عدم القيام بأي شيء عند السؤال عن مكوّنات الثيم الفرعي
إذا سار كل شيء بشكل صحيح، فيجب أن تتمكن الآن من الانتقال إلى My Themes على https://discourse.theme-creator.io/ ورؤية ثيمك الجديد في قائمة الثيمات على اليسار.
لعرض هذه التغييرات في الوقت الفعلي، انقر على اسم ثيمك، ثم في أسفل منطقة المعلومات، انقر على معاينة
يبدأ Theme CLI الآن أيضًا بمراقبة أي تغييرات في المجلد الجديد الذي تم إنشاؤه، وسيحفظ، بالإضافة إلى تحديث الثيم على theme-creator مع كل تغيير.
الخطوات الأولى
أنشأ Discourse Theme CLI هيكلًا لثيم داخل المجلد الذي حددناه في الأمر الذي نفّذناه سابقًا. يتم توليد الكثير من الملفات التي لن نستخدمها، لذا سنقوم بحذف كل شيء باستثناء ما يلي:
common/common.scss
desktop/desktop.scss
mobile/mobile.scss
about.json
داخل المجلد، نفّذ أيضًا rm -rf .git لإزالة تتبع إصدارات git، فهو لن يكون مطلوبًا في هذا الدليل.
يجب أن يبدو مجلد ثيمك الآن هكذا:
من الجدير بالذكر أن الأنماط التي نضيفها إلى هذه الملفات ستظهر في حالات الاستخدام المقابلة لها. ستُطبَّق الأنماط في common.scss على سطح المكتب والجوال، بينما ستُطبَّق الأنماط في desktop.scss فقط على التصفح عبر سطح المكتب، وتلك الموجودة في mobile.scss ستُطبَّق فقط على واجهات الجوال.
مرحبا عالم (بالألوان)
تستخدم Discourse SCSS لتنسيقها، لذا لاستغلال الأنماط بأفضل شكل، قد ترغب في الاطلاع على SASS، لكن إذا لم تفعل، فستتمكن من متابعة هذا الدليل على أي حال.
حسنًا، الآن لنصل إلى ما كنا جميعًا ننتظره… التصميم!
حاليًا، لا تحتوي about.json لدينا على أي مخططات ألوان (color_schemes) محددة، لذا الصق الكود التالي في ذلك القسم ثم احفظ.
{
"name": "my theme",
"about_url": null,
"license_url": null,
"assets": {},
"color_schemes": {
"Default": {
"primary": "222222",
"secondary": "ffffff",
"tertiary": "0088cc",
"quaternary": "e45735",
"header_background": "ffffff",
"header_primary": "333333",
"highlight": "ffff4d",
"danger": "e45735",
"success": "009900",
"love": "fa6c8d"
}
}
}
إذا كان متصفحك مفتوحًا، فلن ترى أي تغييرات قد دخلت حيز التنفيذ، لأن هذا هو مخطط الألوان الافتراضي المستخدم عندما لا يوجد مخطط.
نظرة عامة على الثيم
لدينا شيء ننفذه فعليًا في هذا الدليل، سأشرح لك كيفية إنشاء ثيم بسيط بناءً على لوحة الألوان هذه.

تغيير لون الخلفية + لون النص الأساسي
لنقم بشيء بسيط جدًا. سنقوم بتغيير قيمة "Secondary" في مخطط الألوان الحالي. لنغيّرها إلى "secondary": "EEF4F7" (هذا يغيّر لون الخلفية). دعونا أيضًا نغيّر قيمة "primary" إلى "203243".
بمجرد تلك السطر، قمنا بالفعل بتغيير مظهر وشعور منتدانا. يمكن إجراء الكثير من التخصيص بمجرد تعديل الألوان في مخطط الألوان وحدها.
استخدام مخطط الألوان
جميع المفاتيح التالية معرّفة في ملف about.json تحت اسم مخطط الألوان المقابل. هذه الأوصاف مرجع جيد لمساعدتك على فهم الغرض الرئيسي من كل اسم متغير:
| اللون | الوصف |
|---|---|
| primary | معظم النصوص، والأيقونات، والحدود |
| secondary | لون الخلفية الرئيسي، ولون النص في بعض الأزرار |
| tertiary | الروابط، وبعض الأزرار، والإشعارات، ولون التمييز |
| quaternary | روابط التنقل |
| header_background | لون خلفية ترويسة الموقع |
| header_primary | النصوص والأيقونات في ترويسة الموقع |
| highlight | لون خلفية العناصر المميزة في الصفحة، مثل المنشورات والمواضيع |
| danger | لون التمييز للإجراءات مثل حذف المنشورات والمواضيع |
| success | يُستخدم للإشارة إلى أن إجراءً ما تم بنجاح |
| love | لون زر الإعجاب |
كل متغير من هذه المتغيرات متاح لنا للاستخدام داخل ملفات SCSS الخاصة بنا كما يلي.
body {
background-color: var(--primary);
}
يتم أيضًا إنشاء إصدارات أخرى من كل لون لاستخدامها. أشياء مثل var(--primary-medium) ، أو var(--primary-very-low) يمكن استخدامها للحصول على درجات مختلفة من نفس اللون.
دعونا نغيّر الألوان الأخرى في مخطط الألوان “Default” لدينا لتطابق هذا:
"Default": {
"primary": "203243",
"secondary": "EEF4F7",
"tertiary": "416376",
"quaternary": "5E99B9",
"header_background": "FaFaFa",
"header_primary": "EEF4F7",
"highlight": "86BDDB",
"danger": "8F393E",
"success": "70DB82",
"love": "FC94CB"
}
يمكنك رؤية جميع المتغيرات المتاحة للاستخدام في ملفات SCSS الخاصة بك إذا نقرت على رابط دليل الأنماط أثناء معاينة ثيمك على theme creator، ثم النقر على الألوان في القائمة الجانبية اليسرى.
دليل الأنماط (Styleguide) قسم مفيد جدًا للاطلاع عليه عند إنشاء ثيم مخصص. سيوضح لك كل ذرّة (Atom) كيف ستبدو عناصر معينة من Discourse مع تطبيق أنماطك.
الغوص في التفاصيل
مع استيعابنا للقسم السابق، أعتقد أنه حان الوقت للغوص قليلاً في عمق ما يمكن فعله في Discourse باستخدام SCSS فقط. (تلميح: الكثير!)
تنسيق الترويسة
ستلاحظ أن تغييراتنا السابقة على مخطط الألوان تركت شيئًا يُرغب في تحسينه في ترويساتنا. الأيقونات بالكاد مرئية!
![]()
تتضمن ترويسة Discourse حاوية (مع لون خلفية) لتخزين شعار الموقع، وكذلك أيقونات التنقل على اليمين. يمكن تخصيص جميع هذه العناصر.
الفئة المستهدفة لتخصيص الترويسة هي .d-header.
في ملف common/common.scss لدينا، لنقم بإضافة ما يلي:
.d-header {
box-shadow: none;
border-bottom: 1px solid var(--primary-low-mid);
height: 5em;
}
سيؤدي هذا إلى إزالة ظل الصندوق (box-shadow) الافتراضي على الترويسة، ومنحها ارتفاعًا أكبر قليلاً، بالإضافة إلى تعيين حد سفلي (border-bottom) لإعطاءنا بعض الفصل.
بالنسبة للأيقونات – داخل أقواس SCSS الخاصة بـ .d-header، لنقم بإضافة هذا المكدس من الكود.
.d-header {
// ...الكود السابق
.d-icon {
color: var(--primary-low-mid);
}
}
يبدو هذا جيدًا، لكن عين حادة ستلاحظ أن ارتفاع الترويسة الزائد قد أعطانا مساحة أقل بين الترويسة وعناصر منتدى Discourse الأخرى!
يتم التحكم في المسافة بين المنطقة الرئيسية والترويسة بواسطة الهدف #main-outlet. لنزِد هذه المسافة قليلاً فقط عن طريق إضافة ما يلي إلى أسفل ملف common/common.scss الخاص بك.
#main-outlet {
padding-top: 6.5em;
}
حاوية التنقل
تتضمن حاوية التنقل العناصر التالية.
![]()
المنطقة الأيسر هي قوائم الفلاتر المنسدلة للفئات/الوسوم، تليها روابط التنقل، وتنتهي بزر موضوع جديد.
قائمة الفئات / الوسوم المنسدلة
لنقم بإجراء بعض التغييرات على هذه المنطقة. للقيام بذلك، أضف ما يلي إلى ملف common.scss الخاص بك.
.navigation-container {
.select-kit.combo-box {
.select-kit-header {
border-radius: 0.9em;
background-color: var(--header_background);
}
}
}
هنا نستهدف .select-kit-header لإعطاء كل منها نصف قطر حواف (border-radius) متطابق، بالإضافة إلى لون خلفية أفتح.
عند النقر على أي من هذين، تفتح قائمة منسدلة.
حاليًا، لديها أيضًا زوايا حادة، لذا دعونا نضيف بعض الأنماط لتدوير هذه الزوايا بالإضافة إلى تغيير لون الخلفية ليكون نفس الترويسة.
.navigation-container {
.select-kit.combo-box {
// ...الكود السابق
&.category-drop,
&.tag-drop {
.select-kit-body {
border-radius: 0.9em;
background-color: var(--header_background);
.select-kit-collection {
background-color: var(--header_background);
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
}
}
}
}
يؤدي هذا إلى المظهر التالي…
إذا نظرت عن قرب، يمكنك رؤية أن تغييراتنا تركت حدًا صغيرًا مرئيًا في أعلى يمين منطقة البحث.
دعونا نصلح هذا بالنظر في فاحص المتصفح الخاص بنا. هذه أداة مفيدة دائمًا لمعرفة الفئات/المعرّفات التي نحتاج إلى استهدافها لتطبيق الأنماط بشكل صحيح.
مع قائمة المنسدلة مرئية، انقر بزر الماوس الأيمن على منطقة البحث و’افحص’ العنصر في متصفحك.
يمكننا رؤية أن هذا الحقل (input) يقع داخل div له فئة اسمها select-kit-filter.
إذا نظرنا إلى القواعد المطبقة على هذا المحدد، يمكننا رؤية أنه لديه حاليًا حد علوي وسفلي، بالإضافة إلى بعض الحشو (padding) المطبق. نريد تغيير تنسيق الحد العلوي فقط.
أضف الكود التالي مكدسًا داخل scss الخاص بـ .select-kit-body من قبل.
.select-kit.combo-box.category-drop,
.select-kit.combo-box.tag-drop {
.select-kit-body {
// ...الكود السابق
.select-kit-filter {
border-top: 0px;
}
}
}
بذلك، يجب أن يبدو كودنا لتنسيق حاوية التنقل هكذا.
.navigation-container {
// قائمة الفئات + الوسوم المنسدلة
.select-kit.combo-box {
.select-kit-header {
border-radius: 0.9em;
background-color: var(--header_background);
}
&.category-drop,
&.tag-drop {
.select-kit-body {
border-radius: 0.9em;
background-color: var(--header_background);
.select-kit-collection {
background-color: var(--header_background);
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
.select-kit-filter {
border-top: 0px;
}
}
}
}
}
روابط التنقل
لنقم بإضافة بعض الأنماط لجعل روابط التنقل هذه تبدو مشابهة لهذا:
![]()
لنستخدم الفاحص مرة أخرى لاكتشاف ما يجب علينا استهدافه هنا.
يمكننا رؤية أن عناصر التنقل لدينا داخل UL له فئة اسمها "nav nav-pills ..."
في ملف common.scss الخاص بنا، تحت القسم السابق، لكن لا يزال مكدسًا داخل navigation-container لنضيف ما يلي:
.nav-pills {
& > li a {
&.active {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--tertiary);
}
}
}
سيستهدف هذا التغيير فقط روابطنا التي لها فئة اسمها active والتي هي أبناء لـ nav-pills. يجب أن يجعل هذا التغيير رابطنا النشط يبدو هكذا:
![]()
هذا جيد، لكنني أود أن يمتد الحد السفلي فقط بقدر طول النص. للقيام بذلك، فوق سطر &.active {، لنضيف ما يلي، والذي سيؤثر على جميع روابط A داخل وسوم <li> للتنقل.
// ...كود آخر
.nav-pills {
& > li a {
padding: 0;
margin-right: 20px;
color: var(--tertiary-high);
border-bottom: 4px solid transparent;
&.active {
// ...المزيد من الكود
}
}
}
الآن، نحتاج إلى تنسيق تأثير “التحويم” (hover) ليكون نفس تأثير “النشط” (active).
تحت &.active السابق لدينا لنضيف
&:hover {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--primary);
}
لذا يجب أن يبدو جميع كود التنقل لدينا هكذا الآن:
// حبوب التنقل
.nav-pills {
& > li a {
padding: 0;
margin-right: 20px;
color: var(--tertiary-high);
border-bottom: 4px solid transparent;
&.active {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--tertiary);
}
&:hover {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--primary);
}
}
}
الأزرار
تأتي أزرار Discourse بأشكال وأحجام عديدة. يمكنك عرض تشكيلة منها في قسم الأزرار من دليل الأنماط.
أود تغيير معظم الأزرار في هذا الثيم لتكون مستديرة مع بعض التنسيق المخصص. سيؤدي هذا إلى تغيير زر + موضوع جديد، وكذلك أزرار أخرى في جميع أنحاء الموقع.
في أسفل ملف common.scss الخاص بنا، لنضيف ما يلي:
.btn {
background-color: var(--header_background);
color: var(--primary);
border-radius: 1.2em;
border: 1px solid var(--primary-low-mid);
.d-icon {
color: var(--primary);
}
&:hover {
background-color: var(--quaternary-low);
color: var(--primary);
.d-icon {
color: var(--primary);
}
}
&.btn-default,
&.btn-primary {
padding: 10px 12px;
}
}
سيجعل هذا أزرارنا تبدو هكذا:

الآن بعد أن قمنا بتنسيق أزرارنا، أود الإشارة إلى شيء ما حول تنسيق الأزرار ولماذا من المهم اختبار جميع تصاميمك.
تفضل بالنقر على موضوع في معاينة موقعك، ثم اضغط على زر رد على رد في الموضوع، أو من زر الرد في أسفل سلسلة الموضوع. ستلاحظ أن تنسيق أزرارنا قد أثر على بعض الأشياء التي ربما لم تكن في بالك.
لا أريد أن تتأثر أزرار تحرير النص هذه بتنسيقي السابق. يتطلب هذا قدرًا أكبر من تعقيد SASS/CSS، لكن يمكننا جعل كودنا :not() لا يؤثر على هذه الأزرار. ![]()
لنضيف هذا السطر من الكود، قبل هدف .btn الحالي لدينا. سيخبر هذا أنماطنا بالتطبيق فقط على الأزرار التي ليست أبناء لـ .d-editor-button-bar.
:not(.d-editor-button-bar) > .btn
حسنًا، نجح ذلك بشكل رائع… لكن انتظر! الآن هناك متمرد غريب يفعل ما يشاء.
![]()
عند فحص هذا في المتصفح، أرى أن لهذا الزر فئة اسمها .select-kit-header لأن النقر على هذه الترس (gear) سيظهر المزيد من الخيارات.
لا أستطيع التأكيد على مدى أهمية استخدام أدوات الفاحص في متصفحك عند إنشاء ثيمات Discourse. إنها أفضل صديق لك للسير معك في هذه الرحلة.
الآن بعد أن عرفنا أننا لا نريد استهداف هذا الزر، لنضيف المزيد من وظيفة :not() إلى كودنا.
:not(.d-editor-button-bar) >
.btn:not(.single-select-header)
سيحدد هذا جميع الأزرار التي ليست أبناء لـ .d-editor-button-bar ولا تملك فئة .single-select-header. أعلم أن هذا مربك قليلاً، لكن داخل Discourse، هناك العديد من الأجزاء المتحركة، لذا أحيانًا يحتاج التنسيق أن يكون محددًا جدًا ليؤثر على العناصر بشكل صحيح.
لاحظت أيضًا أن تنسيقنا الحالي يؤثر على زر إغلاق النافذة المنبثقة (modal) بشكل غير مريح. النقر على أي شيء يفتح نافذة منبثقة سيسمح لك برؤية هذا، أو أسهل من ذلك، يمكننا الانتقال إلى قسم النوافذ المنبثقة في دليل الأنماط.
لإصلاح هذا، سأضيف هدفًا آخر إلى كودنا.
:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close)
الانتقال إلى الأمام…
أرى زرًا آخر واحدًا لا يبدو أنه تأثر بكودنا. إنه زر التتبع (Tracking) الموجود في أسفل سلسلة منشورات الموضوع تمامًا.

سأضيف السطر التالي، بعد فاصلة، إلى كود .btn الحالي لدينا.
:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close),
.topic-notifications-button > .select-kit > .btn
سيستهدف هذا الزر الذي يظهر في هذا القسم بشكل صحيح، ولأغراض الوقت الحالي، انتهينا من تنسيق المنطقة العلوية من منتدانا.
لا تتردد في ضبط أي من المعلمات في css الخاص بك. كلما لعبت أكثر مع هذه الأنماط ورأيت ماذا وكيف تؤثر على html، تعلمت أكثر!
إلى أين نتجه من هنا
كان الغرض من هذا الدليل هو الخدش في السطح لكيفية تخصيص ثيمك الخاص لـ Discourse. آمل أن يكون لديك الآن فهم أعمق لكيفية استهداف مناطق من التطبيق لتخصيصاتك الخاصة.
تذكر يمكن تخصيص الكثير من الأشياء باستخدام SCSS فقط. إذا كنت ترغب في الغوص في التفاصيل بشكل أعمق في تطويرك، فأوصي بقراءة المقالات المرتبطة في أعلى هذا المنشور.
لا تتردد في طرح أي أسئلة وسأحاول بكل سرور مساعدتك، أو توجيهك في الاتجاه الصحيح.
هذا المستند مُدار بإصدارات - اقترح تغييرات على github.










