التغييرات القادمة في بث المنشورات - كيفية تجهيز الثيمات والإضافات

نحن نتراجع عن نظام عرض “الودجات” القديم، ونستبدله بمكونات Glimmer الحديثة.

لقد قمنا مؤخرًا بتحديث تدفق المنشورات باستخدام مكونات Glimmer. ستأخذك هذه الدليل خطوة بخطوة في عملية نقل الإضافات والمظاهر (themes) الخاصة بك من النظام القديم القائم على الودجات إلى تطبيق Glimmer الجديد.

لا تقلق — عملية النقل هذه أكثر بساطة مما قد تبدو عليه للوهلة الأولى. لقد صممنا النظام الجديد ليكون أكثر بديهية وقوة من نظام الودجات القديم، وستساعدك هذه الدليل في إتمام العملية.

الجدول الزمني

هذه تقديرات قابلة للتغيير

الربع الثاني 2025:

  • :white_check_mark: اكتمل التنفيذ الأساسي
  • :white_check_mark: البدء في ترقية مكونات الإضافات والمظاهر الرسمية
  • :white_check_mark: تم التفعيل على Meta
  • :white_check_mark: نشر نصائح الترقية (هذه الدليل)

الربع الثالث 2025:

  • :white_check_mark: إكمال ترقية مكونات الإضافات والمظاهر الرسمية
  • :white_check_mark: تعيين glimmer_post_stream_mode الافتراضي إلى auto وتمكين رسائل الإهمال في وحدة التحكم (console)
  • :white_check_mark: تفعيل رسائل الإهمال مع شريط تحذير للمسؤول (مخطط له في يوليو 2025)
  • يجب تحديث الإضافات والمظاهر من جهات خارجية

الربع الرابع 2025:

  • :white_check_mark: تفعيل تدفق المنشورات الجديد افتراضيًا
  • :white_check_mark: إزالة إعداد ميزة العلم (feature flag) والكود القديم

ماذا يعني هذا بالنسبة لي؟

إذا كانت أي من الإضافات أو المظاهر الخاصة بك تستخدم أي واجهات برمجة تطبيقات (APIs) لـ ‘widget’ لتخصيص تدفق المنشورات، فستحتاج إلى تحديثها لتعمل مع الإصدار الجديد.

كيف يمكنني تجربة تدفق المنشورات الجديد؟

لتجربة تدفق المنشورات الجديد، ما عليك سوى تغيير إعداد glimmer_post_stream_mode إلى auto في إعدادات موقعك. سيؤدي هذا إلى تمكين تدفق المنشورات الجديد إذا لم يكن لديك أي إضافات أو مظاهر غير متوافقة.

عندما يتم تعيين glimmer_post_stream_mode على auto، يقوم Discourse تلقائيًا باكتشاف الإضافات والمظاهر غير المتوافقة، وإذا وجد أيًا منها، فسترى رسائل تحذير مفيدة في وحدة تحكم المتصفح تحدد بالضبط أي الإضافات أو المظاهر تحتاج إلى تحديث، جنبًا إلى جنب مع تتبعات المكدس (stack traces) لمساعدتك في العثور على الكود ذي الصلة.

ستساعدك هذه الرسائل في تحديد الأجزاء بالضبط من إضافاتك أو مظاهرك التي تحتاج إلى تحديث لتكون متوافقة مع تدفق منشورات Glimmer الجديد.

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

لدي إضافات أو مظاهر مخصصة مثبتة. هل أحتاج إلى تحديثها؟

ستحتاج إلى تحديث إضافاتك أو مظاهرك إذا قامت بأي من التخصيصات التالية:

  • استخدام decorateWidget، changeWidgetSetting، reopenWidget أو attachWidgetAction على هذه الودجات:

    • actions-summary
    • avatar-flair
    • embedded-post
    • expand-hidden
    • expand-post-button
    • filter-jump-to-post
    • filter-show-all
    • post-article
    • post-avatar-user-info
    • post-avatar
    • post-body
    • post-contents
    • post-date
    • post-edits-indicator
    • post-email-indicator
    • post-gap
    • post-group-request
    • post-links
    • post-locked-indicator
    • post-meta-data
    • post-notice
    • post-placeholder
    • post-stream
    • post
    • poster-name
    • poster-name-title
    • posts-filtered-notice
    • reply-to-tab
    • select-post
    • topic-post-visited-line
  • استخدام إحدى طرق واجهة برمجة التطبيقات (API methods) التالية:

    • addPostTransformCallback
    • includePostAttributes

:light_bulb: إذا كان لديك امتدادات تستخدم أيًا من التخصيصات المذكورة أعلاه، فسترى تحذيرًا في وحدة التحكم يحدد أي إضافة أو مكون يحتاج إلى ترقية عند زيارة صفحة موضوع.

معرف الإهمال هو: discourse.post-stream-widget-overrides

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

ما هي البدائل؟

يمنحك تدفق منشورات Glimmer الجديد عدة طرق لتخصيص كيفية ظهور المنشورات:

  1. مخارج الإضافات (Plugin Outlets): لإضافة المحتوى في نقاط محددة في تدفق المنشورات.
  2. المحولات (Transformers): لتخصيص العناصر، أو تعديل هياكل البيانات، أو تغيير سلوك المكونات.

استبدال includePostAttributes بـ addTrackedPostProperties

إذا كانت إضافتك تستخدم includePostAttributes لإضافة خصائص إلى نموذج المنشور، فستحتاج إلى تحديثها لاستخدام addTrackedPostProperties بدلاً من ذلك.

قبل:

api.includePostAttributes('can_accept_answer', 'accepted_answer', 'topic_accepted_answer');

بعد:

api.addTrackedPostProperties('can_accept_answer', 'accepted_answer', 'topic_accepted_answer');

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

أنماط النقل الشائعة

استخدام مخارج الإضافات (Plugin Outlets)

تُعد مخارج الإضافات الأداة الرئيسية لإضافة المحتوى في نقاط محددة في تدفق المنشورات. فكر فيها على أنها مواقع مخصصة يمكنك من خلالها حقن محتوى مخصص.

هي المفتاح للانتقال بعيدًا عن زخارف الودجات.

يغلف تدفق منشورات Glimmer المحتوى الذي يتم تخصيصه غالبًا داخل مخارج. استخدم دوال واجهة برمجة التطبيقات renderBeforeWrapperOutlet و renderAfterWrapperOutlet لإدراج المحتوى قبلها أو بعدها.

1. استبدال زخارف الودجات بمخارج الإضافات

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

قبل:

// جزء من مهيئ في إضافة

import { withPluginApi } from "discourse/lib/plugin-api";
// ... استيرادات أخرى

function customizeWidgetPost(api) {
  api.decorateWidget("post-contents:after-cooked", (helper) => {
    const post = helper.getModel();
    if (post.post_number === 1 && post.topic.accepted_answer) {
      return helper.attach("solved-accepted-answer", { post });
    }
  });
}

export default {
  name: "extend-for-solved-button",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizeWidgetPost(api);
    });
  }
};

بعد:

// جزء من مهيئ .gjs في إضافة

import Component from "@glimmer/component";
import { withPluginApi } from "discourse/lib/plugin-api";
import SolvedAcceptedAnswer from "../components/solved-accepted-answer";
// ... استيرادات أخرى

function customizePost(api) {
  api.renderAfterWrapperOutlet(
    "post-content-cooked-html",
    class extends Component {
      static shouldRender(args) {
        return args.post?.post_number === 1 && args.post?.topic?.accepted_answer;
      }

      <template>
        <SolvedAcceptedAnswer 
          @post={{@post}} 
        />
      </template>
    }
  );
}

export default {
  name: "extend-for-solved-button",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizePost(api);
    });
  }
};

2. إضافة محتوى بعد اسم الناشر

إذا كانت إضافتك تضيف محتوى بعد اسم الناشر، فستستخدم واجهة برمجة التطبيقات renderAfterWrapperOutlet مع مخرج post-meta-data-poster-name.

قبل:

// جزء من مهيئ في إضافة

import { withPluginApi } from "discourse/lib/plugin-api";
// ... استيرادات أخرى

function customizeWidgetPost(api) {
  api.decorateWidget(`poster-name:after`, (dec) => {
    if (!isGPTBot(dec.attrs.user)) {
      return;
    }

    return dec.widget.attach("persona-flair", {
      personaName: dec.model?.topic?.ai_persona_name,
    });
  });
}

export default {
  name: "ai-bot-replies",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizeWidgetPost(api);
    });
  }
};

بعد:

// جزء من مهيئ .gjs في إضافة

import Component from "@glimmer/component";
import { withPluginApi } from "discourse/lib/plugin-api";
// ... استيرادات أخرى

function customizePost(api) {
  api.renderAfterWrapperOutlet(
    "post-meta-data-poster-name", 
    class extends Component {
      static shouldRender(args) {
        return isGPTBot(args.post?.user);
      }

      <template>
        <span class="persona-flair">{{@post.topic.ai_persona_name}}</span>
      </template>
    }
  );
}

export default {
  name: "ai-bot-replies",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizePost(api);
    });
  }
};

3. إضافة محتوى قبل محتوى المنشور

// جزء من مهيئ .gjs في مظهر

import Component from "@glimmer/component";
import { withPluginApi } from "discourse/lib/plugin-api";
// ... استيرادات أخرى

function customizePost(api) {
  api.renderBeforeWrapperOutlet(
    "post-article",
    class extends Component {
      static shouldRender(args) {
        return args.post?.topic?.pinned;
      }

      <template>
        <div class="pinned-post-notice">
          هذا موضوع مثبت
        </div>
      </template>
    }
  );
}

export default {
  name: "pinned-topic-notice",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizePost(api);
    });
  }
};

4. إضافة محتوى بعد محتوى المنشور

// جزء من مهيئ .gjs في مظهر

import Component from "@glimmer/component";
import { withPluginApi } from "discourse/lib/plugin-api";
// ... استيرادات أخرى

function customizePost(api) {
  api.renderAfterWrapperOutlet(
    "post-article",
    class extends Component {
      static shouldRender(args) {
        return args.post?.wiki;
      }

      // في مكون حقيقي، ستستخدم قالبًا مثل هذا:
      <template>
        <div class="wiki-post-notice">
          هذا المنشور هو ويكي
        </div>
      </template>
    }
  );
}

export default {
  name: "wiki-post-notice",
  initialize() {
    withPluginApi((api) => {
      customizePost(api);
      // ... تخصيصات أخرى
    });
  }
};

استخدام المحولات (Transformers)

تُعد المحولات طريقة قوية لتخصيص مكونات Discourse. تتيح لك تعديل البيانات أو سلوك المكون دون الحاجة إلى تجاوز المكونات بأكملها.

إليك بعض محولات القيم الأكثر صلة بتخصيص تدفق المنشورات:

اسم المحول الوصف السياق
post-class تخصيص فئات CSS المطبقة على عنصر المنشور الرئيسي. { post }
post-meta-data-infos تخصيص قائمة مكونات元 البيانات المعروضة للمنشور. يتيح هذا إضافة أو إزالة أو إعادة ترتيب عناصر مثل تاريخ المنشور، مؤشر التعديل، إلخ. { post, metaDataInfoKeys }
post-meta-data-poster-name-suppress-similar-name تحديد ما إذا كان يجب كتم عرض الاسم الكامل للمستخدم عندما يكون مشابهًا لاسم المستخدم الخاص به. أعد true للكتم. { post, name }
post-notice-component تخصيص أو استبدال المكون المستخدم لعرض إشعار المنشور. { post, type }
post-show-topic-map التحكم في ظهور مكون خريطة الموضوع في المنشور الأول. { post, isPM, isRegular, showWithoutReplies }
post-small-action-class إضافة فئات CSS مخصصة لمنشور إجراء صغير. { post, actionCode }
post-small-action-custom-component استبدال منشور إجراء صغير قياسي بمكون Glimmer مخصص. { post, actionCode }
post-small-action-icon تخصيص الأيقونة المستخدمة لمنشور إجراء صغير. { post, actionCode }
poster-name-class إضافة فئات CSS مخصصة لحاوية اسم الناشر. { user }

1. إضافة فئة مخصصة إلى المنشورات

// جزء من مهيئ في إضافة
import { withPluginApi } from "discourse/lib/plugin-api";

function customizePostClasses(api) {
  api.registerValueTransformer(
    "post-class",
    ({ value, context }) => {
      const { post } = context;

      // إضافة فئة مخصصة للمنشورات من مستخدم معين
      if (post.user_id === 1) {
        return [...value, "special-user-post"];
      }

      return value;
    }
  );
}

export default {
  name: "custom-post-classes",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizePostClasses(api);
    });
  }
};

2. إضافة元 بيانات مخصصة للمنشور

يسمح محول post-meta-data-infos بإضافة مكونات مخصصة إلى قسم元 بيانات المنشور.

// جزء من مهيئ في إضافة
import { withPluginApi } from "discourse/lib/plugin-api";

function customizePostMetadata(api) {
  // تعريف مكون ليتم استخدامه في قسم元 البيانات
  // يجب إنشاء المكون خارج دالة استدعاء المحول،
  // وإلا فقد يسبب مشاكل في الذاكرة.
  const CustomMetadataComponent = <template>...</template>;

  api.registerValueTransformer(
    "post-meta-data-infos",
    ({ value: metadata, context: { post, metaDataInfoKeys } }) => {
      // إضافة المكون فقط لمنشورات معينة
      if (post.some_custom_property) {
        metadata.add(
          "custom-metadata-key",
          CustomMetadataComponent,
          {
            // وضعه قبل التاريخ
            before: metaDataInfoKeys.DATE,
            // وبعد علامة التبويب الرد
            after: metaDataInfoKeys.REPLY_TO_TAB,
          }
        );
      }
    }
  );
}

export default {
  name: "custom-post-metadata",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizePostMetadata(api);
    });
  }
};

إليك مثال من العالم الحقيقي من إضافة discourse-activity-pub:

// جزء من مهيئ في إضافة discourse-activity-pub
import { withPluginApi } from "discourse/lib/plugin-api";
import ActivityPubPostStatus from "../components/activity-pub-post-status";
import {
  activityPubPostStatus,
  showStatusToUser,
} from "../lib/activity-pub-utilities";

function customizePost(api, container) {
  const currentUser = api.getCurrentUser();

  const PostMetadataActivityPubStatus = <template>
    <div class="post-info activity-pub">
      <ActivityPubPostStatus @post={{@post}} />
    </div>
  </template>;

  api.registerValueTransformer(
    "post-meta-data-infos",
    ({ value: metadata, context: { post, metaDataInfoKeys } }) => {
      const site = container.lookup("service:site");
      const siteSettings = container.lookup("service:site-settings");

      if (
        site.activity_pub_enabled &&
        post.activity_pub_enabled &&
        post.post_number !== 1 &&
        showStatusToUser(currentUser, siteSettings)
      ) {
        const status = activityPubPostStatus(post);

        if (status) {
          metadata.add(
            "activity-pub-indicator",
            PostMetadataActivityPubStatus,
            {
              before: metaDataInfoKeys.DATE,
              after: metaDataInfoKeys.REPLY_TO_TAB,
            }
          );
        }
      }
    }
  );
}

export default {
  name: "activity-pub",
  initialize(container) {
    withPluginApi((api) => {
      customizePost(api, container);
      // ... تخصيصات أخرى
    });
  }
};

5. إدراج محتوى قبل أو بعد المحتوى المطبوخ (cooked) للمنشور

إذا كانت إضافتك تضيف محتوى بعد النص في المنشور، فستستخدم واجهة برمجة التطبيقات renderAfterWrapperOutlet مع مخرج post-content-cooked-html.

قبل:

// جزء من مهيئ في إضافة
import { withPluginApi } from "discourse/lib/plugin-api";

function customizeCooked(api) {
  api.decorateWidget("post-contents:after-cooked", (helper) => {
    const post = helper.getModel();
    if (post.wiki) {
      const banner = document.createElement("div");
      banner.classList.add("wiki-footer");
      banner.textContent = "هذا المنشور هو ويكي";
      element.prepend(banner);
    }
  });
}

export default {
  name: "wiki-footer",
  initialize() {
    withPluginApi((api) => {
      // ... تخصيصات أخرى
      customizeCooked(api);
    });
  }
};

بعد:

// جزء من مهيئ في إضافة (.gjs)
import Component from "@glimmer/component";
import { withPluginApi } from "discourse/lib/plugin-api";

// تعريف مكون ليتم استخدامه في مخرج الإضافة
class WikiBanner extends Component {
  static shouldRender(args) {
    return args.post.wiki;
  }

  <template>
    <div class="wiki-footer">هذا المنشور هو ويكي</div>
  </template>
}

function customizePost(api) {
  // استخدم renderBeforeWrapperOutlet لإضافة محتوى قبل محتوى المنشور
  api.renderAfterWrapperOutlet(
    "post-content-cooked-html",
    WikiBanner
  );
}

export default {
  name: "wiki-footer",
  initialize() {
    withPluginApi((api) => {
      customizePost(api);
      // ... تخصيصات أخرى
    });
  }
};

دعم النظامين القديم والجديد أثناء فترة الانتقال

بصفتك مؤلف إضافة أو مظهر، قد ترغب في دعم النظامين أثناء فترة الانتقال لضمان عمل امتداداتك مع تدفقي المنشورات القديم والجديد.

إليك نمطًا تستخدمه العديد من الإضافات الرسمية:

// solved-button.js
import Component from "@glimmer/component";
import { withSilencedDeprecations } from "discourse/lib/deprecated";
import { withPluginApi } from "discourse/lib/plugin-api";
import RenderGlimmer from "discourse/widgets/render-glimmer";
import SolvedAcceptedAnswer from "../components/solved-accepted-answer";

function customizePost(api) {
  // تخصيصات تدفق منشورات glimmer
  api.renderAfterWrapperOutlet(
    "post-content-cooked-html",
    class extends Component {
      static shouldRender(args) {
        return args.post?.post_number === 1 && args.post?.topic?.accepted_answer;
      }

      <template>
        <SolvedAcceptedAnswer 
          @post={{@post}} 
          @decoratorState={{@decoratorState}} 
        />
      </template>
    }
  );

  // ...

  // تغليف كود الودجات القديم مع إسكات تحذيرات الإهمال
  withSilencedDeprecations("discourse.post-stream-widget-overrides", () =>
    customizeWidgetPost(api)
  );
}

// كود الودجات القديم
function customizeWidgetPost(api) {
  api.decorateWidget("post-contents:after-cooked", (helper) => {
    let post = helper.getModel();

    if (helper.attrs.post_number === 1 && post?.topic?.accepted_answer) {
      // استخدم RenderGlimmer لعرض مكون Glimmer في نظام الودجات
      return new RenderGlimmer(
        helper.widget,
        "div",
        <template><SolvedAcceptedAnswer @post={{@data.post}} /></template>
        null,
        { post }
      );
    }
  });
}

export default {
  name: "extend-for-solved-button",
  initialize(container) {
    const siteSettings = container.lookup("service:site-settings");

    if (siteSettings.solved_enabled) {
      withPluginApi((api) => {
        customizePost(api);
        // ... تخصيصات أخرى
      });
    }
  },
};

أمثلة من العالم الحقيقي

إليك روابط لسحب طلبات (pull requests) هجرة فعلية من إضافاتنا الرسمية. تظهر هذه كيفية تحديث كل نوع من أنواع التخصيص:

استكشاف الأخطاء وإصلاحها

موقعي يبدو معطلاً بعد تفعيل تدفق المنشورات الجديد

  • أعد تعيين glimmer_post_stream_mode إلى disabled
  • تحقق من وحدة التحكم (console) بحثًا عن رسائل خطأ محددة
  • قم بتحديث الإضافات/المظاهر المشكلة قبل المحاولة مرة أخرى

لا أرى أي تحذيرات، لكن تخصيصاتي لا تعمل

  • تحقق من أن تخصيصاتك تستهدف الودجات المذكورة أعلاه
  • تأكد من أنك تختبر على صفحة الموضوع مع موضوعات تكون فيها تخصيصاتك مرئية

هل تحتاج إلى مساعدة؟

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

تم تمكين بث Glimmer Post على Meta.

إذا اكتشفت أي مشاكل، فيرجى نشرها أدناه.

أثناء ترقية مكوناتي، واجهت بعض الأكواد الغريبة:

أولاً، أنا في حيرة من أمري بشأن @user={{@post}}. هل يمكن أن يكون هذا خطأ مطبعي؟

ثانياً، لماذا يعتبر post-avatar-flair و UserAvatarFlair عناصر منفصلة؟ بالإضافة إلى ذلك، لماذا لا يكون post-avatar-flair غلافًا مثل المنافذ الأخرى القريبة؟

إنه يعمل، لذلك لا أعتقد أنه خطأ مطبعي. ربما في هذا الموقع، يحتوي كائن المنشور على جميع السمات التي يتوقع مكون UserAvatarFlair العثور عليها في الوسيطة @user؟ أتفق على أنه يبدو غريباً!

بناءً على وصف طلب السحب، يبدو أن هذه الأشياء تم إجراؤها من أجل الاتساق مع منافذ ‘avatar-flair’ المماثلة الأخرى (والتي ربما تم تقديمها قبل أن تكون ‘منافذ الإضافات المغلفة’ شيئاً)

لقد قمنا للتو بدمج طلب سحب (pull request) يمكّن Glimmer Post Stream افتراضيًا.

بعد التحديث التالي، ستستخدم المواقع المتوافقة تلقائيًا Post Stream الجديد. المواقع التي تستخدم إضافات غير متوافقة ستعود إلى الإصدار القديم وستعرض تحذيرات في وحدة تحكم المتصفح.

حاليًا، يمكنك فرض استخدام Post Stream القديم يدويًا عن طريق تعيين glimmer_post_stream_mode إلى disabled.

إذا واجهت أي مشاكل، فيرجى الإبلاغ عنها أدناه.

أعتقد أنني أحصل على تحذير بسبب هذا الرمز الذي يرتبط بعد ذلك بهذا الموضوع:

api.changeWidgetSetting('post-avatar', 'size', '120');

كيف يمكنني تحديث ذلك للنظام الجديد؟

شيء من هذا القبيل:

api.registerValueTransformer("post-avatar-size", () => {
    return "120";
});

لطيف، شكراً لك.

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

مرحباً @Boost. :smiley:

ماذا تقصد عندما تقول إن التجاوزات غير موصى بها للاستخدام بعد؟ إذا كان موقعك جاهزًا، فسيتم تحويله إلى Glimmer Post Stream تلقائيًا.

عندما تقوم بتحديث تثبيت Discourse الخاص بك في المرة القادمة، سيتم تمكين Glimmer Post Stream افتراضيًا حتى للمواقع التي لا تزال تحتوي على تخصيصات غير متوافقة.

في الواقع، تم الآن تعطيل جميع أنظمة عرض الويدجت، لذلك لن يتم عرض أي تخصيص يعتمد على الويدجت بعد الآن.

في الوقت الحالي، يمكن للمسؤول في المواقع غير المتوافقة إعادة تمكين السلوك القديم عن طريق تعديل قيم الإعدادات التالية:

  • glimmer_post_stream_mode
  • deactivate_widgets_rendering

لإعادة تمكين Glimmer Post Stream، يجب تغيير كلا الإعدادين.

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

الخيار الموجود ضمن الإعدادات التجريبية يحذر بوضوح من استخدامه:

تمكين التنفيذ الجديد لتدفق المشاركات ‘glimmer’ في وضع ‘auto’ لمجموعات المستخدمين المحددة. هذا التنفيذ قيد التطوير النشط، وليس مخصصًا للاستخدام الإنتاجي. لا تقم بتطوير السمات/الإضافات بناءً عليه حتى يتم الانتهاء من التنفيذ والإعلان عنه.

لذلك، فإن الصياغة قوية جدًا في القول بأنه “ليس مخصصًا للاستخدام الإنتاجي. لا تقم بتطوير السمات/الإضافات بناءً عليه”.

هذا هو شرح الخيار Glimmer post stream mode auto groups.

إمساك جيد. لقد فاتنا هذا.

أصبح Glimmer Post Stream هو الافتراضي، ويعتبر إصدار الأداة المصغرة قديمًا ومن المقرر إزالته بالفعل. سأقوم بتحديث وصف الإعداد.

تم دمج طلب السحب (PR) الذي يزيل الأداة بعد البث.