تغييرات العناوين القادمة - إعداد السيمات والإضافات

We’ve recently been working on updating Discourse’s header from the legacy ‘widget’ rendering system to modern Glimmer components. This change is now available in Discourse core behind the glimmer header mode site setting.

:timer_clock: Approximate Timeline

(very rough estimates - subject to change in either direction)

Q1 2024:

  • :white_check_mark: core implementation finished & enabled on Meta

  • :white_check_mark: upgrade advice published; console deprecation messages enabled

  • :white_check_mark: work begins to update all official and third-party plugins/themes

Q2 2024:

  • :white_check_mark: start enabling new header implementation by default

  • :white_check_mark: official and third-party themes/plugins are ready for the upgrade

  • :white_check_mark: Deprecation messages start triggering an admin warning banner for any remaining issues

Q3 2024:

  • :white_check_mark: Announcement topic posted for wider visibility: Preparing your community for behind-the-scenes header changes

  • :white_check_mark: w/c 5th August 2024 (v3.4.0.beta1): new header enabled for all sites by default. It will still be possible for admins to switch back to the old header by toggling the ‘glimmer header mode’ site setting.

  • :white_check_mark: w/c 2nd September 2024: final removal of feature flag and legacy code

:eyes: What Does it Mean for Me?

If your plugin or theme uses any ‘widget’ APIs to customize the header, those will need to be updated for compatibility with the new header.

:person_tipping_hand: How Do I Try the New Header?

In the latest version of Discourse, the new header is automatically enabled when all your themes/plugins are compatible.

If your themes/plugins are not compatible, then the legacy header will still be used, and a warning will be printed to the console alongside the existing deprecation messages. A warning banner will also be shown to admins in the UI.

In the unlikely event that this automatic system does not work as expected, you can temporarily override this ‘automatic feature flag’ via the glimmer header mode site setting. If you do that, please let us know the reason in this topic.

:technologist: Do I Need to Update My Plugin/Theme?

To determine whether your customization needs to be updated, check if it uses decorateWidget, changeWidgetSetting, reopenWidget or attachWidgetAction on any of these widgets:

  • header
  • site-header
  • header-contents
  • header-buttons
  • user-status-bubble
  • sidebar-toggle
  • header-icons
  • header-topic-info
  • header-notifications
  • home-logo
  • user-dropdown

or uses one of these plugin API methods:

  • addToHeaderIcons
  • addHeaderPanel

All of these things will now cause deprecation messages to be printed to the console. Deprecation IDs are:

  • discourse.add-header-panel
  • discourse.header-widget-overrides

:warning: If you use more than one theme in your instance, be sure to check all of them.

Admin notice

As of June 20, 2024, we’ve enabled the admin notice for the deprecations above.

If your instance was deployed after this date and your instance’s current plugins, theme, or theme components triggers one of the deprecation warnings, the following message will be displayed only for the admins*:

This message is just to alert the admins that they need to take action soon to modernize the affected customizations: the old customizations will still work until we remove the legacy codebase.

:twisted_rightwards_arrows: What Are the Replacements?

Each theme/plugin is different, but here is some guidance for the most common use cases:

addToHeaderIcons

:information_source: For custom header icons, we recommend removing your code and installing the official Custom Header Links (Icons) Theme Component. If that doesn’t meet your requirements, see below for information for details on the required code changes:

The addToHeaderIcons plugin API has been deprecated in favor of the new headerIcons API. It exists to allow adding, removing, or re-ordering of icons in the header. It requires a Component to be passed.

The component can be passed as so:

Before After
api.addToHeaderIcons(“widget-foo”) api.headerIcons.add(“foo”, FooIcon)
api.decorateWidget(“header-icons:before”, () => return helper.h(“div”, “widget-foo”)) api.headerIcons.add(“foo”, FooIcon, { before: “search” })
api.decorateWidget(“header-icons:after”, () => return helper.h(“div”, “widget-foo”)) api.headerIcons.add(“foo”, FooComponent, { after: “search” })

This example uses Ember’s Template Tag Format (gjs) to define a component inline and pass it to the headerButtons.add API:

// .../discourse/api-initializers/add-my-button.gjs

import DButton from "discourse/components/d-button";
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.0", (api) => {
  api.headerIcons.add("some-unique-name", <template>
    <li><DButton class="icon btn-flat" @href="/u" @icon="address-book" /></li>
  </template>);
});

Or for a dropdown, you could use <DMenu instead of <DButton:

import DButton from "discourse/components/d-button";
import { apiInitializer } from "discourse/lib/api";
import DMenu from "float-kit/components/d-menu";

export default apiInitializer("1.0", (api) => {
  api.headerIcons.add("some-unique-name", <template>
    <li>
      <DMenu class="icon btn-flat" @icon="address-book">
        <DButton @translatedLabel="User 1" @href="/u/user1" />
        <DButton @translatedLabel="User 2" @href="/u/user2" />
        <DButton @translatedLabel="User 3" @href="/u/user3" />
      </DMenu>
    </li>
  </template>);
});

Example upgrade commits:

decorateWidget("header-buttons:*")

:information_source: For custom header links, we recommend removing your code and installing the official Custom Header Links Theme Component. If that doesn’t meet your requirements, see below for information for details on the required code changes:

The header-buttons widget has been deprecated and we have introduced a headerButtons plugin API. It exists to allow adding, removing, or re-ordering of buttons in the header. It requires a Component to be passed.

Before After
api.decorateWidget(“header-buttons:before”) api.headerButtons(“button-name”, ButtonComponent, { before: “auth” })
api.decorateWidget(“header-buttons:after”) api.headerButtons(“button-name”, ButtonComponent, { after: “auth” })

changeWidgetSetting(...) for the header widgets

:information_source: The most common uses of changeWidgetSetting can be achieved using these theme components:

If these don’t fit your use-case, read on…

Some customizations on the header widgets were using the changeWidgetSetting API.

Although, there is no direct replacement for customizations like the one above, due to how the Glimmer components fields work, we introduced a new plugin API on Discourse 3.3.0.beta3 to handle some of these cases.

registerValueTransformer can be used to override values that were tagged in the source code as overridable, this is a similar approach to how plugin outlets work.

We already added two transformers for the use cases we found to be common in our source code base:

  • home-logo-href: can be used to override the URL in the home logo anchor. See the section home-logo below for examples.

  • header-notifications-avatar-size: can be used to change the size of the image fetched to the user avatar in the header. Example:

The code below:

api.changeWidgetSetting(
  "header-notifications",
  "avatarSize",
  settings.header_avatars_size
);

Would be converted to:

api.registerValueTransformer(
  "header-notifications-avatar-size",
  () => settings.header_avatars_size
);

These transformers need to be added to the Discourse source code. If you need a different one, please let us know posting your use case below.

More details about the new value transformer APIs can be found here.

home-logo

We have introduced a home-logo plugin outlet in replacement of home-logo:before or home-logo:after widget decorations. You can utilize the automatic __before and __after naming in your connector file to specify where your custom content should be placed.

More details on before/after connector file naming can be found here.

Before After
api.decorateWidget(“home-logo:before”) Move content to /connectors/home-logo__before
api.decorateWidget(“header-buttons:after”) Move content to /connectors/home-logo__after)

Altering the home-logo anchor URL:

A very common need is altering the URL the home-logo links to. We introduced the home-logo-href value transformer to address this. Examples:

  • to change the link to a static URL

    api.registerValueTransformer("home-logo-href", () => "https://example.com");
    
  • to return a dynamic URL based on the current user

    api.registerValueTransformer("home-logo-href", () => {
      const currentUser = api.getCurrentUser();
      return `https://example.com/${currentUser.username}`;
    });
    
  • to return a URL based on a theme-component setting

    api.registerValueTransformer("home-logo-href", () => {
      return settings.example_logo_url_setting;
    });
    

:sos: What about other customizations?

If your customization cannot be achieved using CSS, PluginOutlets, or the new APIs we’ve introduced, please let us know by creating a new Dev topic to discuss.

:sparkles: How do I update a theme/plugin to support both old and new header?

All the new APIs and plugin outlets listed in this document are supported on both the new and the old header. So you only need to make one update to your theme/plugin now, and users will be ready for the switch.

31 إعجابًا

ولكن كيف يمكنني تعريف FooIcon؟

في إضافة، حاولت إنشاء /assets/javascripts/discourse/components/server-link.js (مثل المكونات الأخرى التي أستخدمها في ملف hbs)

import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";

export default Component.extend({
// هل يجب أن يذهب شيء ما إلى هنا؟
});

و assets/javascripts/discourse/templates/components/server-link.hbs مع
this is a link (أعتقد أنه يمكنني جعله رابطًا إذا نجحت في تشغيل “Hello, world” هذا)

المثال أعلاه يحتوي على const IconWithDropdown = ... ولكن أين يجب أن يذهب ذلك؟ حاولت وضعه في مُهيئ (حيث كان api.decorateWidget) ولكنه لا يبدو كـ JavaScript صالح بالنسبة لي أو لـ Ember، على أفضل تقدير.

قبل ذلك كان لدي مصفوفة headerlinks وكنت أقوم بـ

        headerLinks.push(
          h(
            `li.headerLink.no-servers`,
            h("a", anchorAttributes, I18n.t("pfaffmanager.no_servers_title"))
          )
        );

لإضافة الروابط التي أردتها. أعتقد أنه إذا تمكنت من جعل

      api.headerIcons.add("foo", ServerLink, { before: "search" });

يعمل، فيمكنني فقط وضعه في الحلقة التي بنت تلك المصفوفة.

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

OMG. هل تذهب مكونات Glimmer إلى assets/javascripts/discourse/component وتذهب مكونات Ember إلى assets/javascripts/discourse/components؟!؟!\n\nلدي الآن server-link.gjs\n\nimport Component from "@ember/component";\nexport default class ServerLink extends Component {\n // Required argument for the URL\n url = null;\n // Optional argument for the link text\n text = 'asdf';\n click() {\n console.log('ServerLink clicked!',this);\n\n }\n // Template for the component\n <template>\n {{log "my template" this}}\n LINK!\n <a href={{this.url}}>{{this.text}}</a>\n </template>\n}\n\n\nوفي تهيئتي هذه:\n\n api.headerIcons.add("foo", ServerLink, { param: "url, yo", before: "search" });\n\n\nالآن لدي شيء في الرأس.\n\nولكن كيف أرسل الأشياء إلى ServerLink؟ أحتاج إلى استدعائه عدة مرات بعناوين URL مختلفة ونصوص مختلفة للنقر عليها. لا يمكنني رؤية الأشياء الموجودة في {} في المكون.\n\nوأنت لا تريد حقًا وضع جافاسكريبت قبل \u003ctemplate\u003e، حيث لن يتم تحليل console.log("") الخاص بي!\n\nلقد حاولت أيضًا القيام بما يلي:\n\n const x = new ServerLink({\n url: "mylink",\n text: "my-text",\n name: 'Bob',\n message: 'Generated from JavaScript',\n });\n \nثم تمرير x بدلاً من ServerLink، ولكن لا يزال لا يوجد نجاح.

إعجابَين (2)

هل تقصد أنك تريد أزرارًا متعددة في الرؤوس بأيقونات/نصوص/عناوين URL مختلفة أو نفس الزر، ولكن اعتمادًا على السياق، يمكن أن يتغير النص/عنوان URL؟

نعم، أنت في فئة - ستقوم بتعريف المتغيرات أو الدوال أو القوالب هناك!

نعم. تتغير الروابط لمستخدمين مختلفين. ربط الكود القديم عبر مصفوفة من servers ودفعها إلى هذه المصفوفة:

            headerLinks.push(
              h(
                `li.headerLink${deviceClass}${newClass}`,
                h("a", anchorAttributes, linkText)
              )
            );

ثم فعلت هذا:

      // api.decorateWidget("header-buttons:before", (helper) => {
      //   return helper.h("ul.pfaffmanager-header-links", headerLinks);
      // });

لذلك كان لدي ما يصل إلى 3 روابط تمت إضافتها إلى الرأس، كل منها يربط بعنوان URL منفصل للخادم.

آها. الآن فهمت.

لا تقلق - لا يزال الاصطلاح هو /components/ :sweat_smile:

(من الناحية الفنية، يمكنك تعريف مكونات gjs وتمريرها كيفما تشاء، لذا يمكنك اختيار أي اسم دليل تريده. لكننا نلتزم بـ /components/.)

نعم هذا سؤال وجيه - سأعمل على كتابة بعض المستندات “من الصفر” حول كيفية إضافة أيقونات إلى الرأس حتى يكون لدينا نقطة مرجعية أفضل.

في هذه الأثناء، قد ترغب في إلقاء نظرة على تحديث discourse-icon-header-links للإلهام. الشيء الرائع في استخدام GJS هو أنه يمكنك تعريف المكونات في أي مكان، ولها وصول إلى المتغيرات في النطاق المحلي.

لذا، إذا قمت بإعادة تسمية المُهيئ الخاص بك إلى .gjs، يمكنك القيام بأشياء مثل

servers.forEach((server) => {
  api.headerIcons.add(`server-${server.id}`, <li><DButton @translatedLabel={{server.name}} @icon="server" /></li>);
});

أو يمكنك تعريف مكون في وقت سابق في نفس الملف، واستخدامه مثل

class ServerButton extends Component {
  get icon(){
    // some logic to decide the icon
  }
  <li><DButton @translatedLabel={{@server.name}} @icon={{this.icon}} /></li>
}

...

servers.forEach((server) => {
  api.headerIcons.add(`server-${server.id}`, <ServerButton @server={{server}} />);
});

أو يمكنك نقل التكرار داخل القالب (مفيد إذا كانت قائمة الخوادم عبارة عن TrackedArray قد تتغير في وقت التشغيل!)

api.headerIcons.add("server-buttons", {{#each servers as |server|}}
    <ServerButton @server={{server}} />
  {{/each}});
7 إعجابات

بينما نعمل على المزيد من أمثلة التعليمات البرمجية التفصيلية

أوه. رائع. اعتقدت أنني جربتها في components ولم تنجح.

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

4 إعجابات

رؤية بصيص أمل!

مرحباً @david و @Arkshine! لقد فعلتها!

ماذااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااااا–

          servers.filter(Boolean).map((server) => {
            const linkHref = `/pfaffmanager/servers/${server.id}`;
            const linkTitle = `click to configure server ${server.id}`;
            let host = String(server.hostname);
            const linkText = host.replace(
              /www.|community.|forums?.|talk.|discourse./,
              ""
            );
            const serverLink = <template>
              <li class="headerLink">
                <a class="btn-flat" href={{linkHref}} title={{linkTitle}}>
                  {{host}}
                </a>
              </li>
            </template>;
            const beforeIcon = ["chat", "search", "hamburger", "user-menu"];
            api.headerIcons.add(host, serverLink, { before: beforeIcon });
          });

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

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

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

5 إعجابات

لقد قمت بتحديث OP ببعض الأمثلة الكاملة لـ gjs، وأدرجت رابطًا إلى وثائق Ember الأصلية. كيف يبدو لك هذا يا @pfaffman؟ هل هناك أي شيء آخر تعتقد أنه يستحق الإضافة؟

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

من الأفضل لأنه يحتوي على مثال عملي. ولكن هل أفهم بشكل صحيح أن هناك مكونات Ember ومكونات Glimmer؟ وإذا كان الأمر كذلك، فيجب أن تقول إن مكون Glimmer مطلوب، على ما أعتقد؟

وربما ترتبط بوثائق Glimmer حول كيفية عمل هذه المكونات؟

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

إعجابَين (2)

إنها قابلة للتبديل تمامًا - يمكنك استخدام مكون Ember كلاسيكي، أو مكون Glimmer. ولكل منهما، يمكنك اختيار تأليفهما باستخدام التنسيق القديم .js/.hbs، أو التنسيق الجديد .gjs.

سأرى ما إذا كان بإمكاني إضافة بعض الروابط إلى وثائق Ember :+1:

4 إعجابات

:mega: اليوم قمنا بدمج هذا التغيير، والذي سيقوم تلقائيًا بتمكين تطبيق الرأس الجديد للمواقع ذات السمات/الإضافات المتوافقة.

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

في حالة عدم احتمال تسبب هذا التغيير التلقائي في حدوث مشكلات، يمكنك تجاوز “علم الميزة التلقائي” هذا مؤقتًا عبر إعداد الموقع glimmer header mode. إذا قمت بذلك، فيرجى إخبارنا بالسبب في هذا الموضوع.

3 إعجابات

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

إذًا هناك خيار وربما طريقة سهلة للحفاظ على الوضع الراهن؟

أو

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

هذا ما وجدته اليوم،

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

أنا أكره إلى حد ما الاضطرار إلى القيام بها في المقام الأول، ولكن قبل أن أصرخ مثل رجل عجوز نفد منه البودينغ، أود أن أعرف، ما ولماذا وإلى أين يتجه هذا؟

أنا أفعل هذا من أجل لقمة العيش وحتى الآن أجد أن أمور جافاسكريبت هذه بعيدة كل البعد عن السهولة.

أنا رجل عجوز وأشعر بألمك.

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

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

لو كنت مكانك (وكنت مثلي، بدون وظيفة ديسكورس بدوام كامل)، لكنت سأنشر في Marketplace. لو كنت أنا، ربما لن أستجيب بأقل من 300 دولار، ولكن هناك فرصة معقولة أن يقوم شخص آخر بذلك مقابل 100 دولار أو 200 دولار. أقدر أن الأمر لن يتعطل مرة أخرى لمدة 5 سنوات أو أكثر.

أعتقد أنه يمكنك التخلص من محدد سمات الهامبرغر واستخدام الشريط الجانبي.

3 إعجابات

رد لطيف وصادق، أقدر ذلك ولكن ليس لدي الكثير لأعمل عليه، ربما هناك المزيد قادم (آمل)

لم أكن أعرف حتى أننا نتعامل مع جافا هنا :man_shrugging:

لا أريد لأحد أن يأخذ حلوىك أيضًا :face_with_hand_over_mouth:

بالتأكيد، ولكن ما هو الهدف المنشود، هذا البرنامج يتعامل مع الكثير من الأشياء التي أتساءل من يرى ما النهاية؟

هل هذا مطلوب ببساطة من ترقية ember؟

لا أعرف لماذا تم إجراء ember أيضًا ولكن إذا كان يعمل فلماذا إصلاحه، أنا متأكد من أن هناك شرحًا طويلاً وعميقًا يؤدي إلى مستقبل الأشياء ولكن أليس هناك رؤية حقيقية لمشاركتها؟

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

هناك المزيد من هذا الصدق الذي تقدمه :grin: صحيح بما فيه الكفاية، وكنت أكثر حماسًا للتعلم، وأكثر طموحًا، وشعرت بأن الأمر يستحق أكثر، تعرضت للضرب والسحق وتركت للموت منذ ذلك الحين

حسنًا، أنت في الرهان، سأقبل هذا الرهان وبما أنك خسرت بالفعل، فأنت تساعدني في هذا، سنكون أصدقاء.

إذًا ربما كنت قد استقلت منذ وقت طويل، كان الضرب والسحق والترك للموت وصفًا مجازيًا، أنا فقط من بقي في عجلة القيادة، أعتقد أن أي شخص آخر في بعض اللوحات يحاول إصلاح المحرك فائق السرعة، لا أعرف لأنني لا أتواصل كثيرًا مع الآخرين، ليس لدينا تمويل، تم تجريدنا (FULL30) من وسائل التواصل الاجتماعي و discourse أيضًا، أتساءل كم عدد العملاء الآخرين الذين قطعتهم discourse طواعية أو كم عدد الآخرين الذين اعتبروا معتقداتهم مسيئة لدرجة أن discourse وضع أموالًا ضدها علنًا؟

ومع ذلك، بينما أتحدث الحقيقة، لا أخذ الإساءة، عش ودع الناس يعيشون، أعرف أن هناك مستقبلًا قادمًا، ما لا أعرفه هو لماذا ما زلت هنا وما زلت أحاول، لكنني أفعل، لذا، سأستمر في المحاولة، مثل AA، فقط لهذا اليوم :hugs:

لكنه كان كل الغضب عندما استخدمته :expressionless:

الشريط الجانبي (هنا) يمكن إغلاقه بقائمة هامبرغر، لا يوجد فرق كبير في الوظيفة، يفتح ويغلق نافذة تنقل، ولكن هل لا يمكن حفظ نافذتي بسهولة؟

نعم، أود بشدة وأفضل أن أدفع لشخص ما لتنظيف الكود المخصص الخاص بي وجعل الأشياء تعمل بشكل جيد، وسأدفع بسعادة، أستمتع بتوظيف الآخرين، مشاركة الثروة، عندما أكبر أريد أن أكون فاعل خير، ولكن اليوم أحتاج إلى فاعل خير :innocent: ومرة أخرى أقدر أي مساعدة يمكن للآخرين تقديمها.

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

إعجابَين (2)

للأسف لا. القدرة على الالتزام بـ “الرأس القديم” هي مجرد شيء مؤقت خلال الفترة الانتقالية. قريبًا، سيكون الرأس الجديد هو الخيار الوحيد.

نعم! يسعدنا دائمًا المساعدة في الأسئلة في Dev. بالإضافة إلى ذلك، فإن مشاركة الكود والحلول علنًا تنشئ موردًا مفيدًا للآخرين.

4 إعجابات

الحمد لله، مجتمعي أكثر انسجامًا مع القضايا الأخرى

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

المفارقة، قد تكون البرمجة هي الأسلحة النارية للمستقبل، وقد تسبب المزيد من الموت والدمار أيضًا، لقد خرجت عن الموضوع

حسنًا، هذا يعني ماذا بالضبط بالنسبة لي، إنشاء مجموعة مستخدم واحدة، عامة وغير مسجلة الدخول ربما؟

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

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


لا أرغب في تعطيل موضوع أي شخص، إذا تم اعتبار أن هذا يجب أن يكون موضوعًا خاصًا به، فأنا على ما يرام

ولكن كيف ستكون هناك علاقة متماسكة حقيقية عندما يشعر الناس بالحاجة إلى إزالة شيء يزعجهم؟

يتطلب الأمر الصبر لفهم الآخرين، تم إزالة الرابط، وأظهر شعارًا مفقودًا بعد ذلك ولكن ليس أثناء النشر، هل هناك مشكلة أخرى في الرأس لمناقشتها؟

كانت مشاركة في منتدى خاص بي كتبها رجل أعتقد أنه في الثمانينيات من عمره، يمكنني التأكد من سؤاله ولكنه يرفض التحدث معي، هل أوبخه أو أحظره أو أنبذه؟

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

بالضبط، لقد وجدت الأخطاء للتو، وأرغب في معالجتها ولكنني لا أفهم السبب الجذري بخلاف أن المستقبل يمضي قدمًا، نحتاج إلى رأس جديد، حسنًا، ما هو المسار الصحيح الذي يجب أن أركز عليه، ضبط بسيط، تصحيح مسار كامل؟

هل نناقش فقط الحاجة إلى العمل على هذه المجالات الثلاثة؟

لدي استخدام مختلط للمكونات، بدأت بدونها ثم تعلمت أنها يمكن أن تكون مفيدة، لم أستخدم المكونات بالكامل ولدي مجموعة مختلطة.

إليك مظهري الخاص بما يستحق بدون المكونات
discourse-full30-ii.zip (10.1 KB)
يمكنني نشرها أيضًا، بعضها، النوافذ المنبثقة، لا تعمل بالفعل مؤخرًا