Bevorstehende Header-Änderungen - Vorbereitungen für Themes und Plugins

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 „Gefällt mir“

Aber wie definiere ich ein FooIcon?

In einem Plugin habe ich versucht, /assets/javascripts/discourse/components/server-link.js zu erstellen (wie für andere Komponenten, die ich in einer hbs-Datei verwende)

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

export default Component.extend({
// muss hier etwas hinein?
});

Und eine assets/javascripts/discourse/templates/components/server-link.hbs mit
this is a link (Ich denke, ich kann es zu einem Link machen, wenn ich dieses “Hallo, Welt” zum Laufen bringe)

Das obige Beispiel hat const IconWithDropdown = ..., aber wo würde das hingehören? Ich habe versucht, es in einen Initialisierer zu setzen (wo api.decorateWidget gewesen war), aber es sieht für mich oder Ember nicht wie gültiges JavaScript aus, soweit ich das beurteilen kann.
Bevor ich ein headerlinks-Array hatte und

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

um die gewünschten Links hinzuzufügen. Ich denke, wenn ich

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

zum Laufen bringe, kann ich es einfach in die Schleife einfügen, die dieses Array erstellt hat.

1 „Gefällt mir“

OMG. Glimmer-Komponenten kommen also in assets/javascripts/discourse/component und Ember-Komponenten in assets/javascripts/discourse/components?!?!\n\nIch habe jetzt eine server-link.gjs\n\nimport Component from \"@ember/component\";\nexport default class ServerLink extends Component {\n // Erforderliches Argument für die URL\n url = null;\n // Optionales Argument für den Linktext\n text = 'asdf';\n click() {\n console.log('ServerLink clicked!',this);\n\n }\n // Vorlage für die Komponente\n \u003ctemplate\u003e\n {{log \"my template\" this}}\n LINK!\n \u003ca href={{this.url}}\u003e{{this.text}}\u003c/a\u003e\n \u003c/template\u003e\n}\n\n\nund in meinem Initializer das:\n\n api.headerIcons.add(\"foo\", ServerLink, { param: \"url, yo\", before: \"search\" });\n\n\nJetzt habe ich etwas in der Kopfzeile.\n\nAber wie übergebe ich Dinge an ServerLink? Ich muss es mehrmals mit verschiedenen URLs und verschiedenen Klicktexten aufrufen. Ich kann die Dinge in diesem {} in der Komponente nicht sehen.\n\nUnd man möchte nicht wirklich JavaScript vor der \u003ctemplate\u003e einfügen, da mein console.log(\"\") nicht analysiert wird!\n\nIch habe auch versucht:\n\n const x = new ServerLink({\n url: \"mylink\",\n text: \"my-text\",\n name: 'Bob',\n message: 'Generated from JavaScript',\n });\n \nund dann x anstelle von ServerLink übergeben, aber immer noch kein Erfolg.

2 „Gefällt mir“

Meinen Sie, dass Sie mehrere Schaltflächen in den Headern mit unterschiedlichen Symbolen/Text/URLs wünschen oder dieselbe Schaltfläche, aber je nach Kontext können sich Text/URL ändern?

Ja, Sie sind in einer Klasse – Sie würden dort Variablen, Funktionen oder Vorlagen deklarieren!

Ja. Die Links ändern sich für verschiedene Benutzer. Der alte Code verknüpfte über ein Array von servers und fügte sie in dieses Array ein:

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

Und dann tat dies:

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

Dann hatte ich bis zu 3 Links, die zum Header hinzugefügt wurden und jeweils zu einer separaten Server-URL verlinkten.

Aha. Jetzt verstehe ich es.

Nein, keine Sorge – die Konvention ist immer noch /components/ :sweat_smile:

(Technisch gesehen können Sie GJS-Komponenten definieren und weitergeben, wie Sie möchten, sodass Sie jeden Verzeichnisnamen wählen können. Aber wir bleiben bei /components/.)

Ja, das ist eine berechtigte Frage – ich werde daran arbeiten, einige Dokumentationen von Grund auf zu schreiben, wie man Icons zum Header hinzufügt, damit wir einen besseren Anhaltspunkt haben.

In der Zwischenzeit möchten Sie vielleicht einen Blick auf das Update von discourse-icon-header-links werfen, um sich inspirieren zu lassen. Das Coole an der Verwendung von GJS ist, dass Sie Komponenten überall definieren können und sie Zugriff auf Variablen im lokalen Geltungsbereich haben.

Wenn Sie also Ihren Initialisierer in .gjs umbenennen, können Sie Dinge tun wie

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

Oder Sie können eine Komponente früher in derselben Datei definieren und sie so verwenden:

class ServerButton extends Component {
  get icon(){
    // Logik zur Bestimmung des Icons
  }
  <li><DButton @translatedLabel={{@server.name}} @icon={{this.icon}} /></li>
}

...

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

Oder Sie könnten die Iteration in die Vorlage verschieben (nützlich, wenn die Liste der Server ein TrackedArray ist, das sich zur Laufzeit ändern kann!)

api.headerIcons.add("server-buttons", {{#each servers as |server|}}
    <ServerButton @server={{server}} />
  {{/each}});
7 „Gefällt mir“

Während wir an detaillierteren Beispielcodes arbeiten

Oh. Hurra. Ich dachte, ich hätte es in components versucht und es funktionierte nicht.

Danke! Ich glaube, ich kann eines dieser Dinge zum Laufen bringen. Der Link zu den Header-Links ist eine große Hilfe. Ich bin ziemlich sicher, dass ich, als ich meinen Code schrieb, genug Verstand hatte, um diese Komponente zu betrachten, um sie herauszufinden.

4 „Gefällt mir“

Ein Hoffnungsschimmer!

Hallo @david und @Arkshine! Ich habe es geschafft!

Whaaaaaaaaaaaaaaaaaaat? Einfach umbenennen? Das ist verrückt. Aber siehe da. Ich habe es getan, und jetzt

          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 });
          });

Und es tut, was es vorher getan hat, was ich wollte!

Ja, das klingt jetzt sehr cool und noch mehr nach dem, was ich will, aber diese Dinge ändern sich nicht so oft, also werde ich es dabei belassen. Wenn sie einen Hostnamen ändern, müssen sie die Seite neu laden, damit sich der Link ändert.

Ich nehme an, Sie werden meinen zusätzlichen Kram hier löschen, wenn Sie die obigen Dinge aktualisieren (oder ich wäre in einem Dokumentationsthema vielleicht nicht so gesprächig gewesen…).

5 „Gefällt mir“

Ich habe die OP mit einigen voll funktionsfähigen gjs-Beispielen aktualisiert und einen Link zur Upstream-Ember-Dokumentation hinzugefügt. Wie sieht das für Sie aus, @pfaffman? Gibt es noch etwas, das Ihrer Meinung nach erwähnenswert wäre?

1 „Gefällt mir“

Es ist besser, da es ein funktionierendes Beispiel gibt. Aber verstehe ich richtig, dass es Ember-Komponenten und Glimmer-Komponenten gibt? Und wenn das stimmt, sollten Sie sagen, dass eine Glimmer-Komponente erforderlich ist, denke ich?

Und vielleicht auf die Glimmer-Dokumentation verlinken, wie diese funktionieren?

Es scheint, dass Sie Inline-Komponenten wie in Ihrem Beispiel haben können, und eine andere Art, bei der Sie sie einer Variablen im selben Date oder in einer anderen Datei zuweisen, die Sie im Komponentenverzeichnis ablegen und dann einbinden? Ich denke, das ist vielleicht zu viel für dieses Thema, aber ich hätte gerne ein eigenes Thema dazu.

2 „Gefällt mir“

Sie sind absolut austauschbar – Sie können eine klassische Ember-Komponente oder eine Glimmer-Komponente verwenden. Und für beide können Sie wählen, ob Sie sie im alten .js/.hbs-Format oder im neuen .gjs-Format verfassen möchten.

Ich werde sehen, ob ich einige Links zur Ember-Dokumentation einfügen kann :+1:

4 „Gefällt mir“

:mega: Heute haben wir diese Änderung zusammengeführt, die die neue Header-Implementierung für Websites mit kompatiblen Themes/Plugins automatisch aktiviert.\n\nWenn Ihre Themes/Plugins nicht kompatibel sind, wird weiterhin der alte Header verwendet und eine Warnung wird neben den bestehenden Deprecation-Meldungen in der Konsole ausgegeben. In naher Zukunft wird diese Konsolenwarnung zu einem Warnbanner in der Benutzeroberfläche hochgestuft.\n\nSollte diese automatische Änderung in dem unwahrscheinlichen Fall Probleme verursachen, können Sie dieses ‘automatische Feature-Flag’ vorübergehend über die glimmer header mode-Site-Einstellung überschreiben. Wenn Sie dies tun, teilen Sie uns bitte den Grund in diesem Thema mit.

3 „Gefällt mir“

Ich hatte nicht vor, Änderungen vorzunehmen, aber die Mitteilungen über die Veralterung sagen mir etwas anderes,

Gibt es also eine Wahl und vielleicht einen einfachen Weg, den Status quo beizubehalten?

oder

Was würde ich verpassen, wenn ich mich dafür entscheiden würde, den alten Header beizubehalten? Ich verstehe nicht, was der neue bedeutet. Ich sehe Gruppeneinstellungen, die individuelle Anpassung für verschiedene Gruppen ist faszinierend, aber was kann individuell gestaltet werden?

Das habe ich heute gefunden:

Ich bin kein Guru oder Experte für diese Änderungen, sie brauchen Zeit und ich mache sie nicht oft genug, um die Techniken wirklich lernen zu wollen, die die Benutzer hier anscheinend leicht verstehen/kennen.

Ich ärgere mich schon ein wenig darüber, dass ich sie überhaupt machen muss, aber bevor ich wie ein alter Mann schreie, dem der Pudding ausgegangen ist, möchte ich wissen, was, warum und wohin das führt?

Ich mache das beruflich und trotzdem finde ich diese JavaScript-Sachen alles andere als einfach.

Ich bin ein alter Mann und ich fühle deinen Schmerz.

Es ist nur der Fortschritt, fürchte ich. Dieses Ember-Upgrade hat eine Menge Dinge kaputt gemacht und es ist noch nicht vorbei.

Du hast darum “gebeten”, als du diese Anpassung vorgenommen hast. Ich wette, in den letzten fünf Jahren hast du ein neues Telefon oder einen neuen Laptop bekommen.

Wenn ich du wäre (und du wärst wie ich, ohne den Vollzeit-Discourse-Job), würde ich im Marketplace posten. Wenn ich ich wäre, würde ich wahrscheinlich nicht unter 300 antworten, aber es besteht eine gute Chance, dass jemand anderes es für 100 oder 200 $ tut. Ich schätze, es wird nicht wieder für weitere 5 Jahre oder mehr kaputt gehen.

Ich denke, den Hamburger-Theme-Selektor kannst du loswerden und die Seitenleiste verwenden.

3 „Gefällt mir“

Nette ehrliche Antwort, schätze ich, aber nicht viel, womit ich arbeiten kann, vielleicht kommt noch mehr (ich hoffe)

Ich wusste nicht einmal, dass wir es hier mit Java zu tun haben :man_shrugging:

Ich möchte auch nicht, dass dir jemand deinen Pudding wegnimmt :face_with_hand_over_mouth:

Sicher, aber was ist das gewünschte Ziel, diese Software befasst sich mit so vielen Dingen, ich frage mich, wer was am Ende sieht?

Ist das einfach wegen des Ember-Upgrades nötig?

Ich weiß auch nicht, warum Ember gemacht wurde, aber wenn es funktioniert, warum reparieren, ich bin sicher, es gibt eine lange, tiefe Erklärung, die alles auf die Zukunft der Dinge hinausläuft, aber gibt es keine wahre Vision, die geteilt werden kann?

Ich besuche andere Foren, die sehr alte Software verwenden, persönlich finde ich Discourse viel besser als alle anderen, aber sie scheinen nicht im Vergleich zu leiden, sie haben die gleichen Wachstumsprobleme, die meisten sind meiner Meinung nach Persönlichkeit vs. Software, zu viele alte Hasen, die ihren Pudding verloren haben, ich frage mich, gibt es eine zukünftige IOT, die all diese Foren buchstäblich obsolet machen wird, wo sie überhaupt nicht funktionieren und Discourse sich dessen bewusst ist und sich vorbereitet?

Da ist mehr von dieser Ehrlichkeit, die du bietest :grin: stimmt, und ich war begieriger zu lernen, ehrgeiziger, fühlte das lohnenswertere, wurde seitdem geschlagen, überfahren und für tot erklärt

ok, du bist dabei, ich nehme diese Wette an und da du bereits verloren hast, hilfst du mir damit, wir werden Freunde sein.

Dann hätte ich wahrscheinlich schon vor langer Zeit aufgegeben, das geschlagen, überfahren und für tot erklärt wurde, war eine etwas euphemistische Beschreibung, es bin nur ich, der noch am Steuer sitzt, ich schätze, jeder andere ist irgendwo in einem Gremium und versucht, den Hyperantrieb zu reparieren, keine Ahnung, da ich nicht oft mit anderen kommuniziere, wir haben keine Finanzierung, wir (FULL30) wurden von Social Media und Discourse deplatformed, ich frage mich, wie viele andere zahlende Kunden Discourse bereitwillig entlassen hat oder wie viele andere als so beleidigend in ihren Überzeugungen galten, dass Discourse öffentlich Geld dagegen gesetzt hat?

Doch während ich die Wahrheit sage, nehme ich keinen Anstoß, leben und leben lassen, ich weiß, dass eine Zukunft kommt, was ich nicht weiß, ist, warum ich immer noch hier bin und immer noch versuche, aber ich bin es, also werde ich weiter versuchen, wie AA, nur für heute :hugs:

Aber es war der letzte Schrei, als ich ihn benutzte :expressionless:

Die Seitenleiste (hier) kann mit einem Hamburger-Menü geschlossen werden, es gibt keinen großen Unterschied in der Funktion, sie öffnet und schließt ein Navigationsfenster, aber meins kann nicht einfach gespeichert werden?

Ja, ich würde gerne jemanden bezahlen, der meinen angepassten Code bereinigt und die Dinge schön zum Laufen bringt, und ich würde gerne bezahlen, ich genieße es, andere zu beschäftigen, den Reichtum zu teilen, wenn ich groß bin, will ich Philanthrop sein, aber heute brauche ich einen Philanthropen :innocent: und wieder schätze ich jede Hilfe, die andere anbieten können.

Die andere Möglichkeit ist, Ihre Community um Hilfe zu bitten, mit der Anpassung aufzuhören, ein neues Thema zu eröffnen, das Ihren Code teilt, und um Hilfe zu bitten. Ich habe in letzter Zeit viel Hilfe in solchen Angelegenheiten erhalten.

2 „Gefällt mir“

Leider nein. Die Möglichkeit, am ‘alten Header’ festzuhalten, ist nur eine vorübergehende Sache während der Übergangszeit. Bald wird der neue Header die einzige Option sein.

Yup! Wir helfen gerne bei Fragen in Dev. Außerdem schafft das öffentliche Teilen des Codes und der Lösungen eine nützliche Ressource für andere.

4 „Gefällt mir“

Puh, meine Community ist mehr auf andere Probleme eingestellt

Sicherlich könnte ich hier teilen, aber dann geht es in die entgegengesetzte Richtung, welcher Programmierer findet Interesse daran, uns zu helfen?

Die Ironie, Programmieren könnte durchaus die Schusswaffen der Zukunft sein, könnte auch weitaus mehr Tod und Zerstörung verursachen, ich schweife ab

Sehr gut, was bedeutet das genau für mich, eine Benutzergruppe erstellen, öffentlich und nicht angemeldet vielleicht?

Diese Gruppeneinstellungen, so nehme ich an, basieren auf Vertrauensebenen im Gegensatz zu tatsächlichen verschiedenen Gruppen, wie einer Jagdgruppe und einer Angelgruppe?

Zuerst muss ich das Ziel verstehen und wo meine Bemühungen als einsamer Wolf den größten Nutzen bringen, Zeit sparen und das benutzerdefinierte Gefühl für mein Forum bewahren.


Ich möchte niemandes Thread entgleisen lassen. Wenn dies als eigener Thread betrachtet wird, ist es für mich in Ordnung.

Aber wie wird es jemals eine echte zusammenhängende Beziehung geben, wenn Menschen das Bedürfnis verspüren, etwas zu entfernen, das sie beleidigt?

Es braucht Geduld, um andere zu verstehen. Der Link wurde entfernt, er zeigte danach ein fehlendes Logo, aber nicht während des Postens, ein weiteres Header-Problem, das besprochen werden muss?

Es war ein Beitrag auf meinem Forum, geschrieben von einem Mann, der meiner Meinung nach weit über 80 ist. Ich könnte es sicher fragen, aber er weigert sich, mit mir zu sprechen. Soll ich ihn beschimpfen, sperren oder meiden?

Nein, warum, weil es einen besseren Weg gibt, aber das bedeutet, dass man mit anderen und ihrer Denkweise zurechtkommen muss. Ich finde gute Menschen in schlechten Gegenden, gute Menschen, die schlecht aussehen, und genau das Gegenteil in beiden.

Genau, ich habe gerade die Fehler gefunden, möchte sie beheben, verstehe aber die Grundursache nicht, außer dass die Zukunft voranschreitet, wir brauchen einen neuen Header, okay, was ist der richtige Kurs, auf den ich mich konzentrieren soll, einfaches Tuning, eine vollständige Kurskorrektur?

Sprechen wir nur darüber, dass diese drei Bereiche bearbeitet werden müssen?

Ich habe gemischte Komponentenverwendung, habe mit keiner angefangen und dann gelernt, dass sie vorteilhaft sein können. Ich bin nie vollständig zu Komponenten übergegangen und habe einen gemischten Beutel.

Hier ist mein Theme, was es wert ist, ohne die Komponenten
discourse-full30-ii.zip (10,1 KB)
Ich kann die auch posten, einige, die Modals, funktionieren neuerdings schon nicht mehr