markdown.it il motore CommonMark utilizzato da Discourse ha una vasta gamma di plugin
Ancore per intestazioni, liste di definizioni, frecce intelligenti e l’elenco continua all’infinito.
Prima un avvertimento
CommonMark è pensato per essere… Comune. Più ti allontani dalla specifica, meno comune sarà il tuo Markdown. Può rendere più difficile la portabilità verso altre soluzioni e, se non si fa attenzione, causare incongruenze interne nell’analisi sintattica. Prima di rielaborare qualsiasi cosa, assicurati di rispondere alla domanda “voglio davvero rielaborare questo?”.
Ho appena finito di rielaborare Discourse Footnote e ho alcune lezioni da condividere su come farlo bene.
Passaggi per i pigri
Se sei pigro e vuoi semplicemente iniziare, il modo più semplice è forcare le note a piè di pagina e scambiare file e nomi di variabili. Sono stato abbastanza attento a garantire che segua le migliori pratiche, quindi dovresti avere un solido esempio.
Mosse di apertura, un riconfezionamento minimo
Da quello che ho capito, la maggior parte dei plugin di markdown.it viene distribuita come file js vanilla. In molti casi, i plugin vengono semplicemente distribuiti come un singolo file js, come questo: markdown-it-mark.js.
Idealmente, vuoi lasciare l’originale intatto, il che significa che puoi semplicemente copiare una versione aggiornata del file nel tuo plugin senza dover armeggiare con il plugin esistente.
Il primo problema che incontrerai è che devi insegnare al tuo plugin a caricare questo JavaScript sul server poiché anche il motore Markdown viene eseguito sul server. Per farlo, puoi semplicemente copiare il file così com’è in assets/javascripts/vendor/original-plugin.js quindi nel tuo file plugin.rb dovresti aggiungere:
# questo insegna al nostro motore markdown a caricare il tuo file js vanilla
register_asset "javascripts/vendor/original-plugin.js", :vendored_pretty_text
Una volta incluso il corpo effettivo del plugin, devi insegnare alla nostra pipeline come caricarlo e inizializzarlo:
Crea un file chiamato assets/javascripts/lib/discourse-markdown/your-extension.js
Questo file verrà caricato automaticamente perché termina con .js E si trova nella directory discourse-markdown.
Un semplice esempio può essere:
export function setup(helper) {
// questo ti permette di caricare la tua estensione solo se un'impostazione del sito è abilitata
helper.registerOptions((opts, siteSettings) => {
opts.features["your-extension"] = !!siteSettings.enable_my_plugin;
});
// metti in whitelist qualsiasi attributo che devi supportare,
// altrimenti il nostro sanificatore li rimuoverà
helper.whiteList(["div.amazingness"]);
// puoi anche fare cose fantastiche come questa
helper.whiteList({
custom(tag, name, value) {
if ((tag === "a" || tag === "li") && name === "id") {
return !!value.match(/^fn(ref)?\d+$/);
}
},
});
// infine questa è la magia che useresti per registrare l'estensione nel
// nostro pipeline. whateverGlobal è il nome del globale che il plugin espone
// prende una singola variabile (md) che viene poi usata per modificare la pipeline
helper.registerPlugin(window.whateverGlobal);
}
Sii sempre in fase di test
Il bin/rake autospec di Discourse è consapevole dei plugin ![]()
Ciò significa che quando aggiungi il file spec/pretty_text_spec.rb ogni volta che lo salvi, il file di test del plugin verrà eseguito.
Lo uso ampiamente perché rende il lavoro molto più veloce.
Diciamo che hai aggiunto un plugin che cambia ogni numero in un post in un cerchio 8, puoi chiamarlo discourse-magic-8-ball.
Ecco come strutturerei i test:
require "rails_helper"
describe PrettyText do
it "can be disabled" do
SiteSetting.enable_magic_8_ball = false
markdown = <<-MD
1 thing
MD
html = <<-HTML
<p>1 thing</p>
HTML
cooked = PrettyText.cook markdown.strip
expect(cooked).to eq(html.strip)
end
it "supports magic 8 ball" do
markdown = <<-MD
1 thing
MD
html = <<-HTML
<p>8 circle thing</p>
HTML
cooked = PrettyText.cook markdown.strip
expect(cooked).to eq(html.strip)
end
end
Potrebbe essere necessario “decorare i post”
In alcuni casi, i plugin funzionano meglio quando aggiungono funzionalità extra “dinamiche” ai tuoi post. Esempi di ciò sono il plugin poll o il plugin footnotes che aggiunge un “…” che mostra dinamicamente un tooltip.
se hai bisogno di “decorare” i post aggiungi assets/javascripts/api-initializers/your-initializer.js
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer((api) => {
const siteSettings = api.container.lookup("service:site-settings");
if (!siteSettings.enable_magic_8_ball) {
return;
}
api.decorateCookedElement((elem) => {
// la tua incredibile magia va qui
});
});
Potrebbe essere necessario “post-elaborare” i post
In alcuni casi potresti aver bisogno di “post-elaborare” i post, il motore di rendering markdown, per progettazione, non è a conoscenza di alcune informazioni come, ad esempio, post_id. In alcuni casi potresti voler accedere lato server al post e all’HTML “cotto”, questo può permetterti di fare cose come attivare processi in background, sincronizzare campi personalizzati o “correggere” l’HTML generato automaticamente.
Per le note a piè di pagina avevo bisogno di un id distinto per ogni nota a piè di pagina, il che significava che avevo bisogno di accesso a post_id, quindi sono stato costretto a apportare modifiche all’HTML nel post processor (che viene eseguito in sidekiq)
Per agganciarti, aggiungeresti quanto segue al tuo file plugin.rb:
DiscourseEvent.on(:before_post_process_cooked) do |doc, post|
doc.css("a.always-bing").each do |a|
# questo dovrebbe sempre andare a bing
a["href"] = "https://bing.com"
end
end
Potrebbe essere necessario del CSS personalizzato
Se vuoi distribuire CSS personalizzato, assicurati di registrare il file in plugin.rb
Aggiungi il tuo css a assets/stylesheets/magic.scss e poi esegui
register_asset "stylesheets/magic.scss"
Ricorda che “ricarichiamo automaticamente” le modifiche in modo che tu possa modificare il CSS del tuo plugin e vedere le modifiche al volo durante lo sviluppo.
Buona fortuna con le tue avventure di riconfezionamento ![]()
Questo documento è controllato tramite versione - suggerisci modifiche su github.