إذن أنت مهتم بتصميم سمة (Theme) خاصة بك لـ Discourse؟ لقد وصلت إلى الموضوع الصحيح ![]()
ستركز هذه الدليل بشكل أكبر على جوانب SCSS/CSS عند العمل مع السمات في Discourse. إذا كنت تمتلك أيضًا معرفة بـ JS/EmberJs/Handlebars، فيمكنك التعمق أكثر من خلال الاطلاع على هذا الدليل:
سأصف لك طريقتي الشخصية في التصميم وإعداد السمات في Discourse. كما هو الحال مع معظم الأمور، توجد طرق عديدة لتنفيذ تصاميمك الخاصة. أستمتع باستخدام أدوات الفحص (Inspector tools) بشكل كبير عند إنشاء السمات، وسأوضح لك في هذا المنشور عدة مرات كيف أقوم بذلك.
إعداد البيئة لتصميم السمات
يرجى قراءة دليل المبتدئين لاستخدام سمات Discourse، وكذلك هيكل السمات… قبل المتابعة. ليست هناك حاجة لمعرفة عميقة في هذه المرحلة، لكن هذه المقالات ستمنحك قدرًا أكبر من الإلمام قبل البدء.
وللعمل بشكل أفضل مع تصميم السمات في Discourse، أقترح إعداد ما يلي لتوفير أسرع عملية تصميم وأكثرها سلاسة. ستتيح لك هذه الخطوات رؤية التغييرات فور إجرائها دون الحاجة إلى “حفظ” وتحديث من لوحة إدارة موقع Discourse.
من الممكن تمامًا العمل من خلال هذا الدليل باستخدام وحدة تحكم الإدارة (بشرط أن تمتلك وصولاً بمستوى المشرف على منتدى Discourse.)
- قم بتثبيت Discourse Theme CLI واقرأ الموضوع لفهم ما يمكنه فعله.
- احصل على مفتاح API من https://discourse.theme-creator.io/
- سجل الدخول باستخدام حسابك في Meta
- انقر على My Themes
- انقر على API Key
- في النافذة المنبثقة، انقر على Generate API Key وانسخ المفتاح الذي تم إنشاؤه لك (سنستخدمه لاحقًا)
تشغيل Discourse Theme CLI
بعد تثبيت Discourse Theme CLI واستعداد مفتاح API الخاص بك، افتح محرر النصوص أو نافذة الطرفية (Terminal) المفضلة لديك، وقم بتغيير دليل العمل إلى المكان الذي تريد إعداد مجلد السمة فيه.
بمجرد الوصول إليه، قم بتشغيل الأمر التالي discourse_theme new your_theme_name وأجب على المطالبات على النحو التالي:
-
ما اسم السمة الذي تفضله؟ اختر اسم السمة
-
هل تريد بدء مراقبة هذه السمة؟ نعم
-
ما هو الرابط الجذري لموقع Discourse الخاص بك؟
https://discourse.theme-creator.io/ -
هل تريد تخزين اسم هذا الموقع في…؟ نعم
-
ما هو مفتاح API الخاص بك؟ أدخل مفتاح API الذي حصلت عليه من أداة إنشاء السمات
-
هل تريد تخزين مفتاح API هذا…؟ نعم
-
اختر إنشاء ومزامنة سمة جديدة عند الطلب
-
اختر عدم فعل شيء عند الطلب بشأن مكونات السمة الفرعية
إذا عمل كل شيء بشكل صحيح، يجب أن تتمكن الآن من التنقل إلى My Themes في https://discourse.theme-creator.io/ ورؤية سمنتك الجديدة في قائمة السمات على اليسار.
لمشاهدة هذه التغييرات في الوقت الفعلي، انقر على اسم السمة، ثم في أسفل منطقة المعلومات، انقر على Preview
يقوم CLI للسمة أيضًا بمراقبة أي تغييرات في المجلد الذي تم إنشاؤه حديثًا، وسيقوم بالحفظ، وكذلك تحديث السمة في أداة إنشاء السمات مع كل تغيير.
الخطوات الأولى
قام Discourse Theme CLI بإنشاء هيكل سمة (scaffolding) لنا داخل اسم المجلد الذي حددناه في الأمر الذي قمنا بتشغيله سابقًا. تم إنشاء العديد من الملفات التي لن نستخدمها، لذا سنقوم بحذف كل شيء باستثناء الملفات التالية:
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 الخاص بنا على أي مخططات ألوان محددة، لذا انسخ الكود التالي إلى هذا القسم ثم احفظه.
{
"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 الخاصة بك إذا قمت بالنقر فوق رابط Style Guide أثناء معاينة سمنتك في أداة إنشاء السمات، ثم النقر على Colors في القائمة اليمنى.
يُعد قسم Styleguide قسمًا مفيدًا جدًا للنظر إليه عند إنشاء سمة مخصصة. سيوضح لك كل Atom كيف سيبدو بعض عناصر Discourse مع تطبيق أنماطك.
التعمق أكثر
مع وجود القسم السابق خلفنا، أعتقد أنه حان الوقت لنغوص أعمق قليلاً في ما يمكن فعله في Discourse باستخدام SCSS فقط. (تلميح: كَثِير!)
تنسيق الرأس (Header)
ستلاحظ أن التغييرات السابقة التي قمنا بها على مخطط الألوان قد تركت شيئًا ما يُرغب به في رؤوسنا. الأيقونات بالكاد مرئية!
![]()
يتضمن رأس Discourse حاوية (مع لون خلفية) لاستضافة شعار الموقع، بالإضافة إلى أيقونات التنقل على اليمين. يمكن تخصيص كل هذه العناصر.
الفئة المستهدفة لتخصيص الرأس هي .d-header.
في ملف common/common.scss الخاص بنا، لنقم بإضافة ما يلي:
.d-header {
box-shadow: none;
border-bottom: 1px solid var(--primary-low-mid);
height: 5em;
}
سيؤدي هذا إلى إزالة ظل الصندوق الافتراضي على الرأس، وإعطائه ارتفاعًا أكبر قليلاً، بالإضافة إلى تعيين حدود سفلية لمنحنا بعض الفصل.
بالنسبة للأيقونات – داخل أقواس SCSS الخاصة بـ .d-header، لنقم بإضافة هذا الكود المتداخل.
.d-header {
// ...previous code
.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 لمنح كل منها نصف قطر حدود متطابق، بالإضافة إلى لون خلفية أفتح.
النقر على أي من هذه العناصر يفتح قائمة منسدلة.
حاليًا، تحتوي أيضًا على زوايا حادة، لذا لنقم بإضافة بعض الأنماط لتدويرها بالإضافة إلى تغيير لون الخلفية ليكون مطابقًا للرأس.
.navigation-container {
.select-kit.combo-box {
// ...previous code
&.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;
}
}
}
}
}
هذا ينتج المظهر التالي…
إذا نظرت عن كثب، يمكنك أن ترى أن تغييراتنا قد تركت حدًا صغيرًا مرئيًا في الزاوية اليمنى العليا لمنطقة البحث.
لنقم بإصلاح ذلك بالنظر في مفتش المتصفح الخاص بنا. هذه دائمًا أداة مفيدة للغاية لمعرفة الفئات/المعرفات التي نحتاج إلى استهدافها لتطبيق الأنماط بشكل صحيح.
مع ظهور القائمة المنسدلة، انقر بزر الماوس الأيمن على منطقة البحث وقم بـ “فحص” العنصر في متصفحك.
يمكننا أن نرى أن هذا الإدخال يقع داخل div بفئة select-kit-filter.
إذا نظرنا إلى القواعد المطبقة على هذا المحدد، يمكننا أن نرى أنه يحتوي حاليًا على حدود علوية وسفلية، بالإضافة إلى بعض الحشو المطبق. نريد فقط تغيير تنسيق الحد العلوي.
أضف الكود التالي المتداخل في .select-kit-body scss من السابق.
.select-kit.combo-box.category-drop,
.select-kit.combo-box.tag-drop {
.select-kit-body {
// ...previous code
.select-kit-filter {
border-top: 0px;
}
}
}
مع ذلك، يجب أن يبدو كودنا لتنسيق حاوية التنقل كالتالي.
.navigation-container {
// Category + Tag Drop Down
.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>.
// ...other code
.nav-pills {
& > li a {
padding: 0;
margin-right: 20px;
color: var(--tertiary-high);
border-bottom: 4px solid transparent;
&.active {
// ...more code
}
}
}
الآن، نحتاج إلى تنسيق تأثير “التحويم” (hover) ليكون مطابقًا لتأثير “النشط” (active).
تحت &.active السابق لدينا، لنقم بإضافة
&:hover {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--primary);
}
لذا يجب أن يبدو كل كود التنقل الخاص بنا الآن كالتالي:
// Nav Pills
.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 بأشكال وأحجام مختلفة. يمكنك رؤية مجموعة منها في دليل Style Guide في قسم الأزرار.
أود تغيير معظم الأزرار في هذه السمة لتكون دائرية مع بعض التنسيقات المخصصة. سيؤدي هذا إلى تغيير زر + New Topic، بالإضافة إلى أزرار أخرى في جميع أنحاء الموقع.
في أسفل ملف 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;
}
}
سيجعل هذا أزرارنا تبدو هكذا:

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










