استبدال أيقونات SVG الافتراضية لـ Discourse بأيقونات مخصصة في سمة

يمكنك استبدال أيقونات SVG الافتراضية في Discourse بشكل فردي أو ككل باستخدام SVG المخصص الخاص بك وتجاوزها ضمن سمة أو مكون سمة.

الخطوة 1 - إنشاء مجموعة أيقونات SVG (Spritesheet)

للبدء، يجب عليك إنشاء مجموعة أيقونات SVG. يمكن أن تحتوي هذه المجموعة على أي شيء بدءًا من أيقونة SVG مخصصة إضافية واحدة وصولًا إلى مجموعة استبدال كاملة تضم المئات.

يجب حفظ مجموعة الأيقونات كملف SVG. من حيث المبدأ، تقوم بتضمين محتويات وسم \u003csvg\u003e من ملف أيقونة SVG الأصلي داخل وسوم \u003csymbol\u003e ومنحها مُعرّفًا جيدًا.

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <symbol id="my-theme-icon-1">
    <!--
      الكود الموجود داخل وسم <svg> من ملف أيقونة SVG المصدر
      هذا عادةً كل شيء بين وسمي <svg>
      (وليس وسم SVG نفسه، الذي تم استبداله بـ <symbol> أعلاه)
      يمكنك نقل أي سمات (مثل ViewBox="0 0 0 0") إلى وسم <symbol>
      -->
  </symbol>

  <symbol id="my-theme-icon-2">
    <!-- كود SVG هنا. أضف المزيد من كتل <symbol> حسب الحاجة.
      -->
  </symbol>
</svg>
  • تأكد من إضافة مُعرّف (ID) مخصص لكل رمز (symbol) في مجموعة الأيقونات. قد يكون من المفيد لسلامتك إضافة بادئة لأسماء المعرفات الخاصة بك باسم السمة الخاصة بك my-theme-icon.

  • لجعل لون الأيقونة ديناميكيًا مثل الأيقونات الحالية، قم بتعيين التعبئة (fill) على currentColor بدلاً من لون ثابت (مثل #333).

  • لتغيير حجم الأيقونة أو توسيطها بشكل صحيح، استخدم السمة viewBox على وسم \u003csymbol\u003e. راجع How to Scale SVG | CSS-Tricks لمزيد من المعلومات.

  • كن منتبهًا لتضارب الأنماط داخل ملفات SVG الخاصة بك. على سبيل المثال، غالبًا ما تحتوي ملفات SVG على نمط مضمن مثل .st0{fill:#FF0000;} محدد. إذا كان لديك العديد من ملفات SVG التي تستخدم نفس الفئات، فقد يتسبب ذلك في حدوث مشكلات (لحل هذه المشكلات، قم بتعديل الفئات لتكون فريدة لكل أيقونة).

  • إذا كان لديك العديد من الأيقونات، فهناك طرق لأتمتة ذلك. https://www.npmjs.com/package/svg-sprite-generator هي أداة بسيطة لسطر الأوامر لدمج ملفات SVG في مجموعة أيقونات.

مثال - مجموعة أيقونات مخصصة واحدة

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <symbol id="bat-icon" viewBox="6 6 36 36">
    <path
      fill="currentColor"
      d="M24,18.2c0.7,0,0.9,0.2,0.9,0.2l0.4-1.7c0,0,0.4,1.5,0.4,2.8c0.2,1.1,2.2,0.4,3.9,0C31.4,19.1,32,16,32,16h16c0,0-9.4,3.5-7,10c0,0-14.8-2-17,7l0,0c-2.2-9-17-7-17-7c2.4-6.5-7-10-7-10h16c0,0,0.6,3.1,2.3,3.5c1.7,0.4,3.9,1.1,3.9,0c0.2-1.1,0.4-2.8,0.4-2.8l0.4,1.7C23.1,18.4,23.4,18.2,24,18.2L24,18.2L24,18.2z"
    />
  </symbol>
</svg>

الخطوة 2 - إضافة مجموعة الأيقونات إلى السمة الخاصة بك

بمجرد إنشاء مجموعة الأيقونات الخاصة بك، تحتاج إلى إضافة ملف SVG إلى المكون/السمة الخاصة بك. يتم ذلك بسهولة عبر واجهة المستخدم، أو يمكنك ترميزه مباشرة في مكون/سمة.

:information_source: بمجرد تحميله إلى أي مكون/سمة مثبتة، يصبح متاحًا في جميع أنحاء مثيلك باستخدام المعرّف الموجود في وسم \u003csymbol\u003e.

عبر واجهة المستخدم

انتقل إلى قسم التحميلات (Uploads) في إعدادات السمة/المكون وأضف ملف المجموعة الخاص بك باسم متغير SCSS هو icons-sprite:

الترميز المباشر في سمة / مكون

أضف ملف مجموعة الأيقونات إلى مجلد /assets الخاص بالسمة. ثم قم بتحديث ملف assets.json الخاص بك في المجلد الجذر.
بالنسبة لملف SVG يسمى my-icons.svg، يجب أن يتضمن ملف about.json الخاص بك ما يلي:

"assets": {
  "icons-sprite": "/assets/my-icons.svg"
}

الخطوة 3 (اختياري) - تجاوز الأيقونات الافتراضية

الآن بعد أن تم تعيين مجموعة الأيقونات الخاصة بك، يمكنك إخبار Discourse باستبدال الأيقونات. هذه هي الطريقة التي يتم بها ذلك من مُهيئ واجهة برمجة التطبيقات (api-initializer):

// {theme}/javascripts/discourse/api-initializers/init-theme.gjs

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  api.replaceIcon("bars", "my-theme-icon-bars");
  api.replaceIcon("link", "my-theme-icon-link");
  // إلخ.
});

المعرّف الأول، bars، هو مُعرّف الأيقونة الافتراضي في Discourse والمعرّف الثاني هو مُعرّف الأيقونة البديلة الخاصة بك. أسهل طريقة للعثور على مُعرّف إحدى أيقوناتنا هي فحص الأيقونة في متصفحك.

هنا يتبع اسم الأيقونة البادئة d-icon-. لذا في هذا المثال، إنها d-unliked

تتبع معظم أيقوناتنا أسماء الأيقونات من https://fontawesome.com/، ولكن هناك استثناءات (وهذا هو السبب في أن التحقق من المعرّف في مُفتشك هو الطريقة الأكثر موثوقية). يمكنك رؤية جميع الاستثناءات في الكتلة const REPLACEMENTS هنا على github.

هذا كل شيء. يمكنك الآن تصميم Discourse باستخدام أيقوناتك المخصصة!


هذه الوثيقة يتم التحكم في إصدارها - اقترح التغييرات على github.

57 إعجابًا

كيف يمكن استهداف أيقونة معينة في عنصر معين؟ في حالتي، أود استبدال أيقونة المستندات في قائمة الشريط الجانبي بأيقونة FA أخرى.

إعجاب واحد (1)

سأقوم بإخفائه باستخدام CSS وإضافة زر جديد له.

Common / CSS

.sidebar-section-wrapper {
  li[data-list-item-name=docs] {
    display: none !important;
  }
}

أضف زرًا جديدًا في المزيد > تخصيص هذا القسم

4 إعجابات

هذا لا يعمل. حاولت القيام بـ:

<script type="text/discourse-plugin" version="0.8">
    api.replaceIcon("shield-halved", "hat-wizard");
</script>

من هنا، ولكن يبدو أنه لا يعمل. أعتقد أن طريقة وسم النص البرمجي معطلة، لأن هذا لا يعمل مع رابط المعاينة. بصراحة لست متأكدًا.

إعجاب واحد (1)

يعمل معي :woman_shrugging:t2:


هل تضعه في علامة التبويب head؟ لقد قمت أيضًا باستبدال الروبوت في الرأس الخاص بي:

قد تحتاج إلى إضافة الأيقونة إلى إعداد SVG icon subset الخاص بالمسؤول.

إعجابَين (2)

[اقتباس=“Lilly، المشاركة: 40، الموضوع: 115736”]
هل تضعها في علامة تبويب الرأس؟
[/اقتباس]

نعم، علامة تبويب الرأس. وعلامة تبويب الرأس (header tab)، لأن الدليل يقول ذلك.

[اقتباس=“Lilly، المشاركة: 40، الموضوع: 115736”]
SVG icon subset
[/اقتباس]
تم. إنه يعمل الآن. شكرا!

إعجاب واحد (1)

@NateDhaliwal هل يمكنك مراسلتي من فضلك؟ أحتاج إلى مساعدة في شيء ما ولا أرى خيار دردشة في ملفك الشخصي. شكراً لك!

إعجاب واحد (1)
بالنسبة للقائمة اليسرى، نعيد تعريف خلفية العنصر بفئة prefix-span داخل فئة Audi */
.navigation-category [data-category-id="6"] .prefix-span {
  background: url("https://raw.githubusercontent.com/tima4502/car-icons/bb0d0fae3e5b66c512a27a130b219ec0ee342ada/audi.svg") center/contain no-repeat !important;

عندما أنقر على الصفحة الرئيسية، يظهر الرمز المربع مرة أخرى! هل يمكنك إخباري بما أفعله بشكل خاطئ؟ وعلى صفحة الفئة نفسها، يعمل الأمر.

مرحباً، هل يمكن لأي شخص توضيح العلاقة بين اسم السمة/المكون، واسم الملف، واسم متغير SCSS، ومعرف الرمز…؟

أحاول استبدال أيقونة المشرف shield-halved بأيقونة خاصة بنا، لكن التعليمات غير واضحة بعض الشيء.

في الخطوة 2:

  • لقطة الشاشة “عبر واجهة المستخدم” تعرض اسم ملف baticonsprite.svg مع اسم متغير SCSS icons-sprite
  • ولكن بعد ذلك في “التشفير الثابت في سمة”، تخبرك بتشفيره الثابت في سمة/مكون
  • ولكن كيف؟ لا أرى ملف assets.json في المحرر. إذا قمت بتصدير المكون، أرى about.json، والذي يعرض الـ sprite الذي قمت بتحميله عبر واجهة المستخدم
  • ولكن هذا المثال يعرض أيضًا اسم ملف مختلف /assets/my-icons.svg - هل المقصود أن يكون هذا هو نفس ملف baticonsprite.svg؟
  • هل هذان طريقتان بديلتان للقيام بنفس الشيء، وتحتاج فقط إلى القيام بواحد أو الآخر، وليس كليهما…؟

في الخطوة 3:

  • ولكن الآن، في api.replaceIcon(), المعامل الثاني لا يستخدم أيًا من المعرفات السابقة، لا icons-sprite أو bat-icon أو baticonsprite.svg أو my-icons.svg. بدلاً من ذلك، نحصل على my-theme-icon-bars جديد تمامًا… مرتبك.
  • هل البادئة my-theme مطلوبة، وإذا كان الأمر كذلك، فمن أين يأتي هذا السلسلة “اسم السمة”؟ مثل هل يجب أن يكون my-theme-bat-icon؟ وماذا لو كان مكونًا، وليس سمة؟
  • وبالنسبة لجزء icon-bars، هل يجب أن يكون:
    • معرف الرمز من XML الخاص بـ SVG spritesheet
    • اسم ملف ملف SVG
    • اسم متغير SCSS الذي تعطيه له
    • مزيج من ما سبق (مثل icons-sprite-bat-icon؟)

وأين تضع فعليًا استدعاء api.replaceIcon()؟ هل من المقبول وضعه في علامة التبويب “JS” لمكون مخصص، والذي يحتوي بالفعل على الكود الأساسي:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
   // your code here
});

أم أنه من الضروري إنشاء علامة <script type=”discourse/plugin”> مخصصة ووضعها في علامة التبويب <head> بدلاً من ذلك؟


آسف لهذا الارتباك.

لقد جربت عدة مجموعات مما سبق ولم أتمكن من عرض الـ sprite الخاص بي مهما حاولت…

ملف XML الخاص بالـ sprite الخاص بي يبدو كالتالي:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">


<symbol id="my-logo" viewBox="0 0 94.652 95.261"><defs><linearGradient id="a" y1="47.631" x2="94.652" y2="47.631" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff593d"/><stop offset="1" stop-color="#ff7751"/></linearGradient></defs><title>d_only</title><path d="M47.326,0H0V95.261H47.326c23.67,0,47.326-21.326,47.326-47.624S71,0,47.326,0Zm0,69.274a21.644,21.644,0,1,1,21.65-21.637A21.635,21.635,0,0,1,47.326,69.274Z" fill="url(#a)"/></symbol>

</svg>

اسم الملف هو my-logo.svg واسم متغير SCSS هو أيضًا my-logo

وفي علامة التبويب “JS” للمكون المخصص، لدي:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
    api.replaceIcon("shield-halved", "my-logo")
});

ولكن لا يبدو أن شيئًا ما يظهر. هل هناك خطوة فاتنيها، أو نوع من استيفاء السلسلة السحري الذي أسأت فهمه…؟

إعجاب واحد (1)

هل تمكن أي شخص من حل هذه المشكلة؟ ما زلت أعاني مع هذا…

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
    api.replaceIcon("shield-halved", "my-logo")
});

لست متأكدًا من أين يأتي المعرّف الثاني (“my-logo”) إذا قمت بتحميل الملف عبر واجهة المستخدم:

لا يعمل كل من $my-logo، و$test، وmy-logo.svg، أو عنوان URL المطلق لملف SVG على القرص، وما إلى ذلك. يتم استبدال الدرع، ولكن لا شيء محله. يصبح SVG مجرد <use href=”#my-logo”> فارغ بدون محتويات.

إعجاب واحد (1)

أخيرًا اكتشفت الأمر (شكرًا لك، كلود)!

إذًا:

  1. لا يهم اسم ملف SVG.

  2. داخل ورقة سبرايت SVG، فإن مُعرِّف الرمز (id) هو ما يحدد اسم الأيقونة النهائي، مثل <symbol id=”my-logo” …>

  3. ولكن يجب أن يكون اسم متغير SCSS بالضبط icons-sprite، وليس له علاقة بمعرِّفات ورقة السبرايت النهائية:

  4. بعد التحميل، سيبدو الأمر كما يلي:


    (لاحظ أنه لا يوجد أثر لاسم ورقة السبرايت / المتغير. يجب أن يكون بالضبط $icons-sprite، مع إضافة علامة الدولار $ تلقائيًا وعدم إدخالها في الخطوة السابقة)

  5. ثم، أخيرًا، في علامة التبويب “JS” في السمة (وليس في <head>)، هذا هو المكان الذي تستخدم فيه مُعرِّف ورقة السبرايت من الخطوة 1:

    import { apiInitializer } from “discourse/lib/api”;
    
    export default apiInitializer((api) => {
    api.replaceIcon(“shield-halved”, “my-logo”)
    });
    

لذا يجب أن يكون اسم متغير SCSS بالضبط icons-sprite، ولا يهم اسم الملف، ويتم تحديد اسم أيقونة API بواسطة مُعرِّف الرمز داخل ورقة السبرايت.

3 إعجابات