Können wir `.gjs` für Routenvorlagen verwenden?

Werden Glimmer-Komponenten derzeit in Routen unterstützt?

Ich vermute, die Antwort für Discourse lautet „nein“, würde mich aber freuen, wenn es anders wäre.

2 „Gefällt mir“

Ja, Sie können .gjs-Dateien für Routen-Templates in Discourse verwenden. Tatsächlich haben wir heute gerade eine ganze Menge davon im Kern konvertiert! Schauen Sie sich discourse/app/assets/javascripts/discourse/app/templates at main · discourse/discourse · GitHub an, um Beispiele zu sehen.

„Jemand“ ist Discourse – wir haben die Entwicklung von ember-route-template gesponsert, und es ist in unserer GitHub-Organisation ;).

Wir sind noch nicht auf dem neuesten Ember 6.x, aber wir verwenden dieses Add-on, um die Funktionalität zu ermöglichen.

5 „Gefällt mir“

Wunderbar! Danke für die schnelle Antwort!

Haha, ich habe nicht einmal gesehen, dass es im Discourse GitHub war. Guter Punkt. :slight_smile:

3 „Gefällt mir“

Das Hinzufügen einer neuen Route zur App war sehr undurchsichtig. Ich werde hier für andere dokumentieren.

Ich wollte eine /print-Route im Stammverzeichnis hinzufügen.

Der endgültige Code, der für mich funktionierte, war wie folgt. county-fence ist mein Plugin-Name, ersetzen Sie ihn also durch Ihren eigenen.

Ember-Route

assets/javascripts/discourse/routes/county-fence-route-map.js.es6

export default function() {
  this.route('print', { path: '/print' });
}

assets/javascripts/discourse/routes/print.js

import Route from "@ember/routing/route";

export default class PrintRoute extends Route {
  model() {
    return { message: "This is a custom print page!" };
  }
}

assets/javascripts/discourse/templates/print.gjs

import RouteTemplate from "ember-route-template";
import ...;

export default RouteTemplate(
  <template>
    ...
  </template>
)

API-Route

plugin.rb

after_initialize do
  require_relative "app/controllers/print_controller"
end

app/controllers/print_controller.rb

# frozen_string_literal: true
# HTTP Status codes: https://github.com/discourse/discourse/blob/main/lib/discourse.rb

class ::CountyFence::PrintController < ::ApplicationController
  requires_plugin CountyFence::PLUGIN_NAME


  def save_print
  end

  def list_prints
    render json: { name: "donut", description: "delicious!" }
  end

  def get_print
  end

end

Discourse::Application.routes.append do
  post "/print" => "county_fence/print#save_print"
  get "/print" => "county_fence/print#list_prints"
  get "/print/:id" => "county_fence/print#get_print"
end
4 „Gefällt mir“

Gibt es eine Möglichkeit, eine leere Seite ohne das Layout, die Navigationsleisten oder jegliches CSS der Website zu erhalten? Ich möchte die Glimmer-Komponente verwenden, aber keiner der Website-Stile ist hilfreich, um eine Druckseite zu erstellen.

Wenn es nur um das Styling für eine tatsächlich gedruckte Seite geht und es Ihnen nichts ausmacht, dass die Navigationsleiste und andere Elemente beim Anzeigen der Seite vorhanden sind, können Sie den CSS-Selektor @media print verwenden, um das Styling beim Drucken zu ändern. Discourse blendet beim Drucken bereits viele Dinge aus (discourse/app/assets/stylesheets/common/printer-friendly.scss at main · discourse/discourse · GitHub). Sie können die Seite mit dem Modus print media simulation im Inspektionsmodus von Firefox in der Vorschau anzeigen. Eine ähnliche Funktion sollte im Inspektionsmodus von Chrome vorhanden sein.

Wenn Sie eine komplett leere Leinwand benötigen, nicht nur im Druckmodus, sondern auch beim normalen Surfen im Web, können Sie einen kleinen CSS-Trick anwenden.
Angenommen, Ihre Glimmer-Komponente hat eine Root-Div mit id=\"print-component__root\", können wir mit einem :has()-Selektor prüfen, ob diese vorhanden ist (oder eine Klasse zum Body aus dem Glimmer-Komponenten-Lifecycle hinzufügen/entfernen) und gezielt Styling anwenden.

body:has(#print-component__root) {
  header,
  .avatar,
  .sidebar-wrapper,
  ... {
    all: unset !important;  // all: unset might be a bit too aggressive
    display: none !important;
  }
}

#print-component__root {
  // normal styling
}

Es mag eine bessere, sauberere Methode geben, die die DOM-Elemente tatsächlich entfernt, aber CSS ist ein guter Workaround, um alles zurückzusetzen.

2 „Gefällt mir“

Mein SCSS wird nicht geladen. Irgendwelche Ideen? Ich habe meine Dateien gemäß dem Chat-Plugin in Core eingerichtet: https://github.com/discourse/discourse/tree/47248573feb648364833254396892bedf83b7166/plugins/chat.

Ich habe in plugins.rb:

register_asset "stylesheets/common/index.scss"

In assets/stylesheets/common/index.scss:

@import "common";

In assets/stylesheets/common/common.scss:

body:has(#print-root) {
  header,
  .avatar,
  .sidebar-wrapper {
    all: unset;  // all: unset könnte etwas zu aggressiv sein
    display: none !important;
  }
}

Nur um sicherzustellen, dass das Problem beim Laden des SCSS und nicht bei einer von mir gegebenen Stilregel liegt, versuchen Sie, einen Stil ohne den :has()-Selektor hinzuzufügen. Etwas wie:

.sidebar-wrapper {
  outline: 5px solid red;
}

Ich würde auch versuchen, Ihren Rails-Server neu zu starten. Ich hatte in der Vergangenheit Probleme, bei denen das Hinzufügen/Entfernen von register_asset-Aufrufen einen vollständigen Neustart des Docker-Containers erforderte.

2 „Gefällt mir“
  • Ich habe den :has()-Selektor entfernt.
  • Den Code in index.scss eingefügt, um zu überprüfen, ob es nicht die @import-Anweisung ist.
  • d/rake assets:clobber tmp:clear und d/rails s ausgeführt.

Bisher lädt nichts.

Die meisten anderen Dateien lösen ein automatisches Neuladen im Browser aus. Diese hier tut das nicht. Ich glaube also, dass register_asset das Problem sein könnte. Ich denke, register asset sucht automatisch im Assets-Ordner? Alle Beispiele, die ich mir ansehe, deuten darauf hin.

1 „Gefällt mir“

d/rails c und DiscoursePluginRegistry.stylesheets offenbaren:

"county-fence"=#Set: {"/src/plugins/county-fence/assets/stylesheets/common/index.scss"}

Also passiert etwas. ^^

1 „Gefällt mir“

Ich habe in den d/rails s-Logs Folgendes gefunden: No such file or directory @ rb_sysopen - /src/app/assets/stylesheets/plugin-cf.scss.

Obwohl das Plugin als county-fence in den Ordner /plugins verlinkt ist und mein Plugin in plugins.rb explizit county-fence heißt, liest ein Teil des Codes den zugrunde liegenden Verzeichnisnamen plugin-cf und trifft Annahmen darüber, wie der kompilierte CSS-Name für mein Plugin lautet.

Ist das ein Fehler oder ein Feature? :smiley:

Ich denke, die Moral von der Geschichte ist: Benennen Sie Ihr Plugin-Verzeichnis unter keinen Umständen anders als den übereinstimmenden Namen Ihres Plugins. Ein korrekt benannter Symlink ist nicht ausreichend.

EDIT: Auch register_asset \"stylesheets/common/index.scss\", plugin: \"county-fence\" ist ein Workaround, der erzwingt, dass der Plugin-Name korrekt gesetzt wird.

Ich habe Probleme mit den Regeln unter body:has(), die angewendet werden. Sie scheinen in der Asset-Kompilierungspipeline nicht aktualisiert zu werden. Ich führe d/rake assets:clobber tmp:clear aus und starte den Server mit d/rails s neu, und sie werden immer noch nicht aktualisiert.

Zum Beispiel kann ich body { background-color: red !important; } in den Abschnitt body:has() einfügen, und es erscheint überhaupt nicht in den Stilen für das Body-Element. Es wird nicht einfach überschrieben – es ist überhaupt nicht in den “Styles” in den Devtools vorhanden.

Wenn ich dieselbe CSS-Zeile außerhalb von body:has() platziere, wird sie einwandfrei angezeigt.

document.querySelector("body:has(#print-root)") !== null gibt in der Browserkonsole true zurück. Und einige Regeln von body:has() werden angewendet.

Ich frage mich, ob es Regeln in der Asset-Generierungspipeline geben könnte, die verhindern, dass diese Änderungen durchkommen.

Ich denke, mein Ansatz dafür ist, die Stile direkt in der Glimmer-Komponente für die Seite einzufügen. Das ist das Einzige, was ich ausprobiert habe und was konsistent funktioniert. Und dann muss ich mich nicht mit den bedingten CSS-Regeln herumschlagen.

Die CSS-Kompilierungs-Pipeline hat mir endlos Probleme bereitet – ich stelle fest, dass sie beim Aktualisieren und Anwenden von Regeln wirklich inkonsistent ist… Dinge verschwinden und ich weiß nicht warum. Ich weiß nicht, ob das etwas mit dem Ausführen in einem Docker-Container zu tun hat? Ich habe meine Symlinks zum Plugins-Ordner komplett entfernt – ich glaube, das hat Probleme mit dem Docker-Volume-Mount und dem Datei-Watching/Neukompilieren verursacht. Ich kann wahrscheinlich ein minimales Repository erstellen, um diese Probleme zu reproduzieren… Ich werde sehen, ob ich das tun kann und es in den nächsten Tagen veröffentlichen.

Eine Nachverfolgung dazu…

Ein von Stripe gerendertes Iframe verursacht nun eine leere Seite am unteren Rand meines Drucklayouts. Das Iframe ist fest mit display: block !important direkt am Element codiert.

Ich denke, ich werde diesen speziellen Fehler umgehen, indem ich das Iframe lösche, wenn diese Route geladen wird… (Übrigens rendert Stripe eine seitenweite Div, die alle Klickereignisse erkennt - was wie eine ziemliche Verletzung der Privatsphäre erscheint… Ich glaube, das stammt vom Abonnement-Plugin.)

Aber ich schaue in die Zukunft und sehe eine lange Reihe von Whack-a-Mole-Fehlerbehebungen auf der Druckseite voraus. Alles, was in Zukunft ein neues Element im Layout einführt, auch wenn es nicht merklich sichtbar ist, könnte dazu führen, dass Drucke fehlschlagen.

Es ist wirklich keine ideale Situation für mich, das Website-Layout für diese Route zu übernehmen. Gibt es eine Möglichkeit, mich abzumelden oder mein eigenes Layout festzulegen?