نوع الكائنات لإعدادات السمة

نقدم نوعاً جديداً type: objects ضمن الأنواع المدعومة لإعدادات السمة، يمكن استخدامه كبديل لنوع json_schema الحالي الذي ننوي إيقافه قريباً.

تعريف إعداد سمة من نوع objects

لإنشاء إعداد سمة من نوع objects، عرّف أولاً مفتاحاً على المستوى العلوي تماماً مثل أي إعداد سمة آخر، وسيُستخدم كاسم للإعداد.

links: ...

بعد ذلك، أضف الكلمات المفتاحية type و default و schema إلى الإعداد.

links:
  type: objects
  default: []
  schema: ...

يشير type: objects إلى أن هذا سيكون إعداداً من نوع objects، بينما تقوم التدوينة default: [] بتعيين القيمة الافتراضية للإعداد إلى مصفوفة فارغة. لاحظ أنه يمكن أيضاً تعيين القيمة الافتراضية إلى مصفوفة من الكائنات، وسنوضح ذلك بعد تعريف schema.

لتعريف المخطط (schema)، عرّف أولاً name الخاص بالمخطط كما يلي:

links:
  type: objects
  default: []
  schema:
    name: link

بعد ذلك، سنضيف الكلمة المفتاحية properties إلى المخطط، والتي ستتيح لنا تعريف والتحقق من شكل كل كائن.

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name: ...

في المثال أعلاه، نوضح أن الكائن link يحتوي على الخاصية name. لتعريف نوع البيانات المتوقعة، يجب على كل خاصية تحديد الكلمة المفتاحية type.

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name:
        type: string

ينص تعريف المخطط أعلاه على أن الكائن link يحتوي على خاصية name من نوع string، مما يعني أنه سيتم قبول قيم نصية فقط لهذه الخاصية. الأنواع المدعومة حالياً هي:

  • string: تُخزن قيمة الخاصية كنص. عيّن textarea: true لاستخدام منطقة نصية قابلة للتوسيع:

    description:
      type: string
      textarea: true
      validations:
        max_length: 500
    
  • integer: تُخزن قيمة الخاصية كعدد صحيح.

  • float: تُخزن قيمة الخاصية كعدد عشري.

  • boolean: قيمة الخاصية هي true أو false.

  • upload: قيمة الخاصية هي رابط URL للمرفق.

  • enum: يجب أن تكون قيمة الخاصية واحدة من القيم المحددة في الكلمة المفتاحية choices.

    links:
      type: objects
      default: []
      schema:
        name: link
        properties:
          name:
            type: enum
            choices:
              - name 1
              - name 2
              - name 3
    
  • categories: قيمة الخاصية هي مصفوفة من معرفات الفئات (category ids) الصالحة.

  • groups: قيمة الخاصية هي مصفوفة من معرفات المجموعات (group ids) الصالحة.

  • tags: قيمة الخاصية هي مصفوفة من أسماء الوسوم (tag names) الصالحة.

  • icon: قيمة الخاصية هي اسم لأيقونة واحدة من مجموعة أيقونات Discourse. تُضاف الأيقونات المختارة تلقائياً إلى ورقة الصور (sprite sheet)، لذا يمكن عرضها دون تسجيلها بشكل منفصل.

بعد تعريف المخطط، يمكن الآن تعيين القيمة الافتراضية للإعداد بتعريف مصفوفة في YAML كما يلي:

links:
  type: objects
  default:
    - name: link 1
      title: link 1 title
    - name: link 2
      title: link 2 title
  schema:
    name: link
    properties:
      name:
        type: string
      title:
        type: string

الخصائص المطلوبة

جميع الخصائص المعرفة تكون اختيارية بشكل افتراضي. لتمييز خاصية كمطلوبة، قم ببساطة بتدوين الخاصية بـ required: true. يمكن أيضاً تمييز الخاصية كاختيارية بتدوينها بـ required: false.

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name:
        type: string
        required: true
      title:
        type: string
        required: false

تعتبر القيم الفارغة لأنواع string و datetime و icon والقوائم الفارغة لأنواع categories و groups و tags كأنها مفقودة: الخصائص المطلوبة ترفضها، بينما الخصائص الاختيارية تتخطى التحقق منها. تعتبر قيمة false كقيمة مضبوطة.

التحقيقات المخصصة

لأنواع خصائص معينة، يوجد دعم مدمج للتحقيقات المخصصة التي يمكن إعلانها بتدوين الخاصية بالكلمة المفتاحية validations.

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name:
        type: string
        required: true
        validations:
          min_length: 1
          max_length: 2048
          url: true

التحقيقات للأنواع string

  • min_length: الطول الأدنى للخاصية. يجب أن تكون قيمة الكلمة المفتاحية عدداً صحيحاً.
  • max_length: الطول الأقصى للخاصية. يجب أن تكون قيمة الكلمة المفتاحية عدداً صحيحاً.
  • url: يتحقق من أن الخاصية هي رابط URL صالح. يمكن أن تكون قيمة الكلمة المفتاحية true/false.

التحقيقات للأنواع integer و float

  • min: القيمة الدنيا للخاصية. يجب أن تكون قيمة الكلمة المفتاحية عدداً صحيحاً.
  • max: القيمة القصوى للخاصية. يجب أن تكون قيمة الكلمة المفتاحية عدداً صحيحاً.

التحقيقات للأنواع tags و groups و categories

  • min: العدد الأدنى للسجلات للخاصية. يجب أن تكون قيمة الكلمة المفتاحية عدداً صحيحاً.
  • max: العدد الأقصى للسجلات للخاصية. يجب أن تكون قيمة الكلمة المفتاحية عدداً صحيحاً.

حل عضوية المجموعة

يمكن لإعدادات الكائنات حل خصائص type: groups إلى قيمة منطقية (boolean) للمستخدم الحالي. هذا مفيد عندما تحتاج كودات السمة فقط إلى معرفة ما إذا كان المستخدم الحالي في إحدى المجموعات المكونة، لأن currentUser.groups تشمل فقط المجموعات المرئية للمستخدم.

أضف resolve_group_membership: true إلى خاصية groups:

menu_sections:
  type: objects
  default:
    - name: section 1
      groups:
        - 1
        - 3
  schema:
    name: menu section
    properties:
      name:
        type: string
      groups:
        type: groups
        resolve_group_membership: true

لا تزال واجهة المستخدم الإدارية والقيمة المخزنة للإعداد تستخدم مصفوفة groups الأصلية. في وقت تشغيل الكائن settings في الواجهة الأمامية، تقوم Discourse بإزالة معرفات المجموعات من كل كائن وإضافة قيمة منطقية بنفس اسم الخاصية مع اللاحقة user_in_:

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // المستخدم موجود في مجموعة واحدة على الأقل مختارة لهذا القسم.
  }
}

هذا الخيار صالح فقط لخصائص مخطط الكائنات ذات type: groups. كما يعمل أيضاً مع مخططات الكائنات المتداخلة ومع المجموعات التلقائية مثل logged_in_users و anonymous_users.

بنية الكائنات المتداخلة

يمكن للكائن أيضاً أن يحتوي على خاصية تتضمن مصفوفة من الكائنات. لإنشاء بنية كائنات متداخلة، يمكن تدوين خاصية بـ type: objects وتعريف schema المرتبط بها.

sections:
  type: objects
  default:
    - name: section 1
      links:
        - name: link 1
          url: /some/url
        - name: link 2
          url: /some/other/url
  schema:
    name: section
    properties:
      name:
        type: string
        required: true
      links:
        type: objects
        schema:
          name: link
          properties:
            name:
              type: string
            url:
              type: string

وصف الإعداد والتوطين

لإضافة وصف للإعداد في الترجمة en، أنشئ ملفاً باسم locales/en.yml بالتنسيق التالي بافتراض إعداد سمة من نوع objects كما هو موضح.

sections:
  type: objects
  default:
    - name: section 1
      links:
        - name: link 1
          url: /some/url
        - name: link 2
          url: /some/other/url
  schema:
    name: section
    properties:
      name:
        type: string
        required: true
      links:
        type: objects
        schema:
          name: link
          properties:
            name:
              type: string
            url:
              type: string
en:
  theme_metadata:
    settings:
      sections:
        description: هذا هو وصف لإعداد السمة sections
        schema:
          properties:
            name:
              label: الاسم
              description: الوصف الخاص بالخاصية
            links:
              name:
                label: الاسم
                description: الوصف الخاص بالخاصية
              url:
                label: URL
                description: الوصف الخاص بالخاصية

هذا المستند يخضع للإصدار والتحكم - اقترح تغييرات على github.

16 إعجابًا

ما زلت غير مقتنع بأن إلغاء نمط مخطط JSON فكرة جيدة.

في حين أن هذه يمكن أن تصبح معقدة للغاية وليست الأكثر “ودية للمطورين” من التنسيقات (لذا هذا تغيير رائع في هذا الصدد)، هناك أدوات عبر الإنترنت للتحقق من صحة مخططات JSON وهو أمر مفيد حقًا للتحقق من كل من المخطط وضد أي بيانات افتراضية.

على سبيل المثال: https://www.jsonschemavalidator.net/

كيف سيعمل ذلك في هذا العالم الجديد؟

إعجابَين (2)

عند تحميل سمة، سنتحقق من صحة البيانات الافتراضية مقابل المخطط المحدد. ومع ذلك، نحن لا نتحقق من صحة تعريف المخطط الآن، ولكن لن يكون من الصعب علينا القيام بذلك. حتى بالنسبة لإعداد المخطط json حاليًا، لا أعتقد أننا نتحقق من صحة البيانات الافتراضية مقابل المخطط المحدد.

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

إعجابَين (2)

بعض الميزات الرائعة هنا:

  • يمكنك التخلص من JSON.parse والوصول مباشرة إلى الإعداد للحصول على الكائن وهو أمر رائع حقًا.

  • مدقق الروابط!

:chefs_kiss: :chefs_kiss:

5 إعجابات

هل هناك أي طريقة لاحترام الأسطر المتعددة في المحرر؟

هذا الافتراضي يعمل:

- name: markdown
  value: > 
    ## Heading
      * first bullet
      * second bullet

ولكن بمجرد تعديل هذا، يتم فقدان عودات العربة

علاوة على ذلك، سيكون من الجيد وجود نوع "نص" يمكنه تخزين بيانات أطول وربما يعرض محرر "مساحة نصية" أكبر

5 إعجابات

إليك بعض الملاحظات:

إعجابَين (2)

لاحظت هذا وقد تم إصلاحه في

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

هل سنتمكن من إعادة ترتيب العناصر في الواجهة؟

على سبيل المثال، هذا هو محرر إعدادات الكائن في مكون سمة التذييل السهل. لا يمكنني إعادة ترتيب أي عناصر في الوقت الحالي:

4 إعجابات

أردت طلب هذه الميزة أيضًا! :+1:


على صعيد آخر، سيكون من المفيد لو احتوى المنشور الأول على معلومات حول خاصية identifier.

قبل النظر إلى صورة Nolo أعلاه، اعتقدت أنه من المستحيل استبدال تسمية الطفل الافتراضية بقيمة خاصية. بعد النظر إلى الكود، وجدت خاصية identifier.

4 إعجابات

إعادة الترتيب هو بالتأكيد شيء تم طرحه داخليًا أيضًا. سأحاول إنجازه هذا الأسبوع.

تم الإحاطة علماً. سأقوم بتحديث المنشور الأول بشأن خاصية identifier.

5 إعجابات

نعم، لاستبدال النظام القديم (الذي سيصبح قريباً قديماً؟) بصيغة JSON، يجب أن يطابق الواجهة القديمة أو يتجاوزها:

بما في ذلك الترتيب.

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

مرحباً، هل هناك أي خطط لدعم أنواع حقول أخرى قريباً؟

على سبيل المثال؛

  • long_string بتنسيق markdown؛ ربما مع شريط أدوات قابل للتخصيص،
  • حقل date (مع قواعد التحقق)،
  • حقل color (مع قواعد التحقق)؟
إعجاب واحد (1)

لا توجد خطة حالية، على الرغم من أنني أتفق على أنه سيكون مفيدًا. أود حقل icon بنفسي.

8 إعجابات

في تجربتي، يبدو أن هذا يعمل مثل الإعدادات المسبقة المحفوظة. في هذا المثال، يمكن أن تستفيد الإدخالات الأولى 2 من هذه الإعدادات المسبقة، ولكن أي شيء بعد ذلك ستظهر جميع الإدخالات الجديدة فارغة في البداية.

هذا يعني أيضًا أنه لا يمكننا تعيين قيم افتراضية لكل حقل. على سبيل المثال، إذا كنت أرغب في الحصول على مربع اختيار، ليبدأ في حالة محددة، فلا يمكنني الحصول عليه.

links:
  type: objects
  default:
    - name: link 1
      title: link 1 title
    - name: link 2
      title: link 2 title
  schema:
    name: link
    properties:
      is_active:
        type: boolean
        default: true

لن يعمل default: true هناك كما هو متوقع.

هل يمكن أن تكون هناك طريقة لتعيين القيم الافتراضية لكل حقل، لكل الإدخالات التي تم إنشاؤها؟

هل هناك طريقة لاستيراد خصائص الكائنات إلى متغيرات في Sass؟

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

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

شكراً لمشاركة المثال! على الرغم من ذلك، نعم.. لا يبدو ذلك مغرياً :upside_down_face:

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

من باب الفضول، دون قضاء الكثير من الوقت في البحث، ما هو وضعنا مع هذا؟

إعجابَين (2)

نعم، إنه ليس جيدًا جدًا، لا تفعل ذلك. :). لقد كان محاولة لمعرفة ما إذا كان ذلك ممكنًا، ولكن ليس نهجًا معقولًا.
أتفق معك؛ سيكون من الرائع وجود طريقة مباشرة! :+1:

أود أن أعرف، أيضًا!
أيضًا، إذا كنت على حق، فستكون هذه هي الميزة الوحيدة المفقودة مع json_schema.

إعجابَين (2)

كنت أبحث عن نوع التحميل ليكون متاحًا، ولكنه غير موجود.
نظرة سريعة على النواة تظهر أنه تم تنفيذ أنواع الموضوع والمنشور والتحميل من جانب الخادم ولكن ليس في الواجهة الأمامية. هل هناك سبب محدد لذلك؟ :thinking: