Barvna shema: Temna
Trenutno dejavna stran: start » sl » Dokumentacija » Razširitve DokuWikija (WvdS) » FluentUI (knjižnica oblikovalskega sistema) » FluentUI: reference komponent » FluentUI: urejevalniki in prikaz kode

FluentUI: urejevalniki in prikaz kode

Nazaj: FluentUI (knjižnica oblikovalskega sistema)


Pet različnih gradnikov za urejanje in prikaz kode ter vprašanje, kateri je za kaj – s sklicem na vir resnice za vsakega.

1. Pregled in namen

Stanje: mešano – pet gradnikov [Live] (vsak s svojim nosilcem, med njimi codeEditor() in htmlSplitEditor()) ter preklop med urejevalnikom in označevanjem (preklop WYSIWYG, namenoma opisan zunaj te strani – nosilec wvdsmd), navedeno po razdelkih.

Ta stran razvrsti pet različnih gradnikov za urejanje in prikaz kode in za vsakega poveže vir resnice – ne nadomešča dokumentacije vtičnikov. Ciljna skupina: vsak razvijalec, ki se mora odločiti, kateri gradnik je pravi za »prikaz kode«, »urejanje kode« ali »urejanje vsebine wikija« (razdelek 5).

2. Predpogoji

  • Za codeEditor() in htmlSplitEditor(): DokuWiki z omogočenim vtičnikom wkfluentui in naloženim helper_plugin_wkfluentui_widgets.
  • Za GeSHi: nobenih – funkcija jedra, vedno na voljo.
  • Za urejevalnik Markdown: omogočen vtičnik wvdsmd, stran ima oznako Markdown (samodejno zaznavanje).

3. Pojmi

Skupni vzorec vseh petih gradnikov: postopna izboljšava nad delujočim poljem textarea – ista konvencija kot pri razširitvah JS v API-ju pomočnika (brez druge poti kode, označevanje ostane oblika shranjevanja).

Gradnik Kaj je Uporaba Nosilec / vir resnice Stanje
GeSHi (izris kode) skladenjsko barvanje ob izrisu – ni urejevalnik, brez lastnega API-ja <code sql>…</code>/<file> v besedilu wikija in ograjeni bloki kode (```lang) v vdelavah Markdown ({{md>…}} / <markdown>); oznaka jezika = ime jezika v GeSHi jedro DokuWiki (inc/parser/xhtml.php → priloženi GeSHi); videz prek žetonov --wk-wiki-code-* izvedeno (jedro)
Urejevalnik izvorne kode CodeMirror, postopno nad navadnim <textarea> – brez JavaScripta polje textarea v celoti deluje vsak skrbniški modul prek codeEditor() (prvi porabnik: delovna površina SQL v wksqliteds) skupna kopija v wkfluentui/cm/ + gradnik codeEditor() (pogodba: razdelka 6/7 spodaj) izvedeno
Deljeni urejevalnik HTML izvorna koda in urejljiv izrisan predogled drug ob drugem; odločilna ostane izvorna koda, predogled pa vanjo zapiše na novo oblikovano kodo skrbniške površine, ki vzdržujejo fragmente HTML (prvi porabnik: upravljanje izsečkov v wksnippet) gradnik htmlSplitEditor() + scripts/htmlsplit.js, predogled v okvirju iframe s peskovnikom (pogodba: razdelka 8/9 spodaj) izvedeno
Standardni urejevalnik DokuWiki urejevalnik strani v jedru: orodna vrstica (krepko/povezava/…) + textarea + predogled, potek osnutka in zaklepanja vsaka stran wikija, do=edit jedro DokuWiki izvedeno (jedro)
Urejevalnik Markdown priloženi EasyMDE na straneh Markdown nadomesti textarea; vrstica z oznako je nevidna, potek shranjevanja in osnutka v DokuWikiju ostane nespremenjen; brez JS ostane textarea strani z oznako Markdown (samodejno zaznavanje) vtičnik wvdsmd – vir resnice: Markdown (wvdsmd) izvedeno

4. Prvi koraki

Najmanjši primer: urejevalnik CodeMirror vklopite nad obstoječim poljem textarea za SQL.

/** @var helper_plugin_wkfluentui_widgets $widgets */
$widgets = plugin_load('helper', 'wkfluentui_widgets');
?>
<textarea id="sql-input" name="sql"></textarea>
<?php echo $widgets->codeEditor('sql-input', 'sql'); ?>

Napačno: codeEditor() usmeriti na textarea, ki ob klicu še ni v DOM (npr. klic pred oznako <textarea>). Aktivacijski HTML se z id sklicuje na element, ki mora obstajati – vrstni red v zgornjem primeru (najprej textarea) je zavezujoč.

5. Uporaba: vodnik »kateri gradnik za kaj«

Potreba Gradnik
prikazati kodo v vsebini <code lang> (GeSHi) – nikoli ne vdelajte urejevalnika
urejati kodo ali SQL v skrbniškem modulu codeEditor() (en klic ob polju textarea, lastna kopija knjižnice v vtičniku ni potrebna)
urejati fragment HTML z vizualnim preverjanjem htmlSplitEditor() (ovije isto polje textarea; za stran z izvorno kodo vsebuje codeEditor())
zapisati polje HTML v obrazcu kot oblikovano besedilo (opis, komentar) htmlSplitEditor() z 'variant' => 'field' – glejte Različica polja
urejati vsebino wikija urejevalnik jedra; strani Markdown samodejno prek wvdsmd
brez posnemanja urejevalnikov Monaco/VS Code namerna meja, enako kot pri mehaniki postavitve (layout)

6. Referenca API: codeEditor()

Metapodatek Vrednost
Jezik PHP
Imenski prostor helper_plugin_wkfluentui_widgets
Datoteka lib/plugins/wkfluentui/helper/widgets.php
Vidnost public
Stabilnost stabilno (stopnja 1)
public function codeEditor(string $textareaId, string $language, array $opts = []): string

Povzetek: vrne aktivacijski HTML brez <script> (atributi data-wk-code-editor) za obstoječe, poimenovano polje textarea; scripts/codeeditor.js (postopna izboljšava) ga ob nalaganju nadomesti s primerkom CodeMirror.

Vrnjena vrednost: string – aktivacijski HTML. Prazen niz pri neznani oznaki $language ali praznem $textareaId – v obeh primerih ostane textarea nedotaknjena kot navadno polje, brez napake.

7. Parametri, možnosti in stanja

Parameter Tip Obvezno Opis
$textareaId string da id obstoječega ciljnega polja textarea
$language string da ena od sql|php|css|javascript|markdown|html; vsaka druga oznaka vrne prazen niz
$opts['submitId'] string ne id gumba za oddajo, ki ga klikne Ctrl+Enter – urejevalnik pred tem sinhronizira vsebino v textarea

Dostop do primerka (odjemalec): wkCodeEditor.get(textareaId) – null, dokler CodeMirror ni naložen oziroma če se ne naloži; razrešite ob kliku, ne ob gradnji strani. Dogodek wk-codeeditor-ready se dodatno sproži na polju textarea.

Zakasnjeno nalaganje: knjižnice se naložijo le na straneh z vsaj eno aktivacijsko oznako – brez povečanja obsega na celotnem spletnem mestu.

Priložena kopija (utemeljen popravek specifikacije): skupna kopija CodeMirror (5.65.16 + načini sql/php/css/javascript/markdown/htmlmixed z odvisnostmi clike/xml/htmlmixed, datoteka z licenco MIT) je v wkfluentui/cm/ – ne v prvotno predvidenem vendor/cm/, ker spletna plast DokuWikija neposreden dostop do imenikov vendor/ zavrne (na tej namestitvi empirično preverjeno, 404).

Obnašanje ob napaki:

Pogoj Obnašanje
neznana oznaka $language vrne prazen niz, textarea ostane nedotaknjena
prazen $textareaId vrne prazen niz
ciljnega polja textarea ni v DOM brez napake PHP (gradnik DOM ne preverja); scripts/codeeditor.js ob nalaganju ne najde cilja in ničesar ne vklopi – tiho zmanjšano delovanje na strani odjemalca

8. Referenca API: htmlSplitEditor()

Metapodatek Vrednost
Jezik PHP
Imenski prostor helper_plugin_wkfluentui_widgets
Datoteka lib/plugins/wkfluentui/helper/widgets.php
Nosilec interakcije lib/plugins/wkfluentui/scripts/htmlsplit.js
Vidnost public
Stabilnost stabilno (stopnja 1)
public function htmlSplitEditor(string $textareaHtml, string $textareaId, array $opts = []): string

Povzetek: že pripravljeno polje textarea, ki ga ustvari klicatelj, ovije z deljenim urejevalnikom: levo izvorna koda (CodeMirror, jezik html – isti gradnik kot v razdelku 6), desno izrisan predogled. Predogled je mogoče urejati; kar spremenite tam, se na novo oblikovano zapiše v izvorno kodo.

Zakaj polje textarea ostane klicatelju: ta knjižnica namenoma nima golega gradnika textarea – ime, velikost, obveznost in oznaka polja v obrazcu spadajo k zaslonu, ne k oblikovnemu sistemu. Gradnik zato dobi pripravljen HTML, ki ga je klicatelj že zaščitil (escape), in okoli njega postavi le okolje. Posledica: poslani POST je z gradnikom ali brez njega enak.

Parameter Tip Obvezno Opis
$textareaHtml string da celoten HTML <textarea …> klicatelja, ki ga je ta že zaščitil (escape)
$textareaId string da njegov id; prazen ⇒ $textareaHtml se vrne nespremenjen
$opts['mode'] string ne začetni pogled source|split|preview (privzeto split); prednost ima pogled, ki ga je uporabnik prej shranil
$opts['editable'] bool ne false ⇒ predogled je samo za branje, skupina za oblikovanje v celoti odpade (privzeto true)
$opts['storageKey'] string ne imenski prostor shranjenega pogleda (wk-htmlsplit:<storageKey> v localStorage); prazen ⇒ pogled se ne zapomni
$opts['submitId'] string ne id gumba za shranjevanje – posreduje se codeEditor(), torej Ctrl+Enter
$opts['lang'] string ne jezik vsebine v predogledu (privzeto $conf['lang'])
$opts['variant'] string ne field ⇒ različica polja (spodaj); mode, editable in storageKey se tedaj ne berejo. Brez te možnosti je izhod deljeni urejevalnik, nespremenjen
$opts['label'] string le polje dostopno ime vnosne površine – v oblikovanem pogledu oznaka polja textarea ni vidna
$opts['rows'] int ne le polje: najmanjša višina v vrsticah (privzeto 6, najmanj 2)

Brez JavaScripta: orodna vrstica ima na strežniku nastavljen hidden (njeni gumbi za pogled in oblikovanje bi bili sicer mrtvi kontrolniki), površina za predogled je prazna in hidden. Ostane natanko polje textarea klicatelja. Vsi gumbi gradnika so type=„button“, polje za naslov povezave pa nima name – poslati se torej ne more nič.

Predogled kot iframe s peskovnikom: sandbox=„allow-same-origin“, brez allow-scripts (oboje skupaj je dokumentirana izjema peskovnika in torej ne bi bilo zaščita). To je nujno, ker smejo vzdrževani fragmenti HTML vsebovati <style> in <script>: izrisan v vrstici bi <style> preoblikoval skrbniško stran okoli sebe. Preverjeno na tej namestitvi – <script> iz fragmenta se ne izvede ne v okvirju ne v nadrejenem dokumentu, njegov <style> učinkuje znotraj okvirja, skrbniška stran pa ostane merljivo nespremenjena. Slogovne datoteke gostiteljske strani se kopirajo v dokument predogleda, da predogled kaže pravo kaskado in ne ročno vzdrževanega približka.

Značke za nadomestne oznake: nadomestne oznake vtičnikov ({{wk:lang>…}}, {{wk:image>…}}) niso HTML. V predogledu postane vsaka od njih nedeljiva značka, ki je ni mogoče urejati, nosi žeton dobesedno in ga dobesedno tudi zapiše nazaj – sicer bi en sam pritisk tipke žeton razbil ali pa bi kodiranje besedila iz < v {{wk:lang>de:< 24 Stunden}} naredilo <, s čimer se vzorec vtičnika, ki žeton uporablja, ne bi več ujemal. Značke nastanejo iz izvorne kode, ne iz razčlenjenega drevesa: samo tam še obstajajo izvorni bajti, samo tam je nadomestna oznaka, ki sama vsebuje HTML (…Industrie-<br/>erfahrung…), en sam žeton, in samo tam je mogoče ločiti položaj besedila od položaja atributa. Nadomestne oznake v vrednostih atributov ostanejo nedotaknjene.

Pot shranjevanja: polje textarea je in ostane polje obrazca. Sprememba v predogledu, ki je ob kliku na Shrani še v času zadržanja, se dokonča v fazi zajemanja (capture) na document – pred prenosom iz CodeMirror v textarea, ki je vezan na sam obrazec. Brez tega vrstnega reda se zadnji pritiski tipk v predogledu ob shranjevanju izgubijo, in to neopazno.

Prvi porabnik: upravljanje izsečkov (wksnippet, do=admin&page=wksnippet&edit=<key>).

Različica polja

Polje HTML v obrazcu ni fragment HTML: njegovo označevanje je oblika shranjevanja, ne predmet dela. Opis, koraki za ponovitev in komentar delovnega elementa so v Azure DevOps taka polja in se tam urejajo kot oblikovano besedilo. 'variant' => 'field' za to ponudi isti mehanizem z drugačnim obrazom.

$ta = $widgets->textArea([
    'name' => 'System.Description', 'id' => 'wk-wi-desc',
    'value' => $html, 'rows' => 10, 'ariaLabel' => 'Opis', 'bare' => true,
]);
echo $widgets->htmlSplitEditor($ta, 'wk-wi-desc', [
    'variant' => 'field', 'label' => 'Opis', 'rows' => 10,
]);
Enako kot deljeni urejevalnik Drugače
polje textarea ostane polje obrazca; nedotaknjeno polje vrne svojo vrednost bajt za bajtom, tudi po preklopu na HTML in nazaj privzeto oblikovano besedilo, izvorna koda je eno stikalo (HTML); brez deljenega pogleda
predogled v okvirju iframe s peskovnikom brez skriptov višina sledi vsebini med rows vrsticami in 60 % okna, celotna površina je vnosno polje
čakajoči vnos se ob oddaji prevzame pisava iz okolice gradnika (v obrazcu 13/18), ne bralna velikost strani
noben kontrolnik nima name ena vrstica: krepko, ležeče, podčrtano, koda, oznake, številčenje, povezava, odstrani oblikovanje, HTML; Ctrl+B/I/U, Ctrl+K
naslov povezave se prikaže šele na ukaz (Escape ga zapre)
brez značk za nadomestne oznake ({{ je v polju besedilo), brez opozorila o odločilni izvorni kodi, brez sporočila o pisanju

Obvezno polje in nadomestno besedilo. Če ima textarea required, ga skript odstrani in ob oddaji preveri sam – prazno je tudi tisto, kar ostane od izpraznjenega polja (<p><br></p>, &nbsp;): ustavi, aria-invalid, rob v barvi napake, sporočilo v vrstici stanja, fokus v polje. Razlog: v oblikovanem pogledu je textarea skrita, skrito obvezno polje pa brskalnik zavrne le v konzoli (»an invalid form control is not focusable«) – gumb bi navidezno ne naredil ničesar. Brez skripta ostane required na polju textarea. placeholder polja textarea se prikaže tudi na oblikovani površini.

Dostopnost. Površina je role=„textbox“ z aria-multiline, ime dobi iz label, aria-required/aria-placeholder pa po polju textarea; ukazi imajo aria-keyshortcuts.

Dve posebnosti brskalnikov, izmerjeni:

  • Koda v vrstici ne obstaja kot ukaz urejevalnika, očiten nadomestek pa odpove: Chrome iz <code>, vstavljenega z insertHTML, naredi <span style="font-family: …">. Element se zato nastavi prek obsega (range); ta en korak ni na skladu za razveljavitev.
  • Označi vse, izbriši, tipkaj je oblikovanje izbrisanega začetka prevzelo kot slog tipkanja – po kodi kot <font face="Consolas…">. Do praznega izbrisana površina se zato začne s praznim odstavkom in svežo vstavitveno točko.

Zaščita pri porabniku. Različica polja je mlajša od gradnika. Starejši komplet možnost prezre in nariše deljeni urejevalnik. Porabnik zato odgovor sprejme le, če ima data-wk-hs-variant="field", sicer nariše svoje polje textarea (tako wkdoadowi).

Prvi porabnik: pogled delovnega elementa (wkdoadowi): opis, koraki za ponovitev, komentar. Ni vključeno: vstavljanje slik (ADO jih naloži kot priloge).

9. Krožna pot: kaj urejanje v predogledu spremeni v izvorni kodi

Urejanje v predogledu pomeni, da brskalnik označevanje na novo serializira. To prinese izgube, zato so tukaj navedene s številkami, ne zamolčane. Če delate le levo v izvorni kodi, ne sprožite ničesar od tega.

Izmerjeno na vseh 55 datotekah izsečkov te namestitve (izvorna koda → predogled → urejanje → izvorna koda):

Rezultat Datoteke
dokument se razčleni enako (elementi, atributi, besedilo) 55 / 55
nadomestne oznake bajtno enake (430) 55 / 55
vsebina <script> in <style> bajtno enaka 55 / 55
datoteka kot celota bajtno enaka 28 / 55
razlika izključno v zamikih 23 / 55
razlika tudi drugje 4 / 55

Štiri odstopanja ne vplivajo na prikaz: znakovne reference za natisljive znake postanejo sam znak (✓ → kljukica, » → francoski narekovaj), poševnica praznega elementa pa odpade (<br/> → <br>).

Razveljavitev: zapis nazaj je ena sprememba v CodeMirror – en sam Ctrl+Z v polju z izvorno kodo razveljavi celotno novo oblikovanje. Orodna vrstica to pove tudi tam, kjer se to zgodi.

Zamik: štirje presledki; element, katerega podrejeni elementi so vsi vrstični, ostane v eni vrstici, dokler vrstica ne preseže 110 znakov. Vsebina <script>, <style>, <pre> in <textarea> se nikoli ne prelomi ali na novo zamakne – tam zamik spremeni pomen, ne videza.

10. Popolni primeri: preklop urejevalnik ↔ označevanje [Live]

Nosilec wvdsmd (polna izvedba 2026-07-14) – vir: lib/plugins/wvdsmd/script.js.

Na straneh Markdown ima orodna vrstica EasyMDE stikalo med pogledom urejevalnika (EasyMDE z orodno vrstico za oblikovanje in predogledom) in pogledom označevanja (surovo polje textarea z vidno vrstico z oznako – enako stanju brez JS). Preklopiti je mogoče kadar koli v obe smeri in učinkuje takoj, brez shranjevanja; nazadnje izbrani pogled se zapomni za vsakega uporabnika (localStorage, wk-editor-view:<login>); vsak preklop se napove prek regije aria-live. Lastnosti:

  1. Označevanje ostane oblika shranjevanja (Markdown) – oba pogleda urejata isto polje textarea, ponovne serializacije ni, zato so preklopi že po zasnovi brez izgub (bajtno enaka izvorna koda, dokazano v preizkusnem zagonu).
  2. Brez JS ostane surovo polje textarea; stikalo obstaja le v pogledu, izboljšanem z JS.
  3. Strani s sintakso DokuWiki obdržijo urejevalnik jedra z njegovo orodno vrstico za sintakso in gumbom »Predogled« – tam je le en pogled za urejanje, stikalo bi bilo brez pomena.

Poglobitev – konkretni ukazi orodne vrstice: dve podstrani dokumentirata, katere žetone sintakse DokuWiki oziroma Markdown vstavljajo orodne vrstice urejevalnikov (EasyMDE za Markdown, orodna vrstica jedra za sintakso DokuWiki), po shemi kategorij predstavitvenih strani DevExpress ASPxHtmlEditor (https://demos.devexpress.com/ASPxHTMLEditorDemos/Default.aspx), vendar prenesene na dejansko ciljno obliko te knjižnice namesto splošnih oznak HTML:

11. Omejitve in robni primeri

  • Seznam jezikov določa GeSHi; neznane oznake se izrišejo kot navadno besedilo (brez napake). Enako velja v vdelavah Markdown: ParsedownRenderer v wvdsdwmd ograjene bloke z znano oznako jezika obarva prek DokuWikijeve poti GeSHi (p_xhtml_cached_geshi()); bloki brez oznake ali z neznano oznako ostanejo surovi <pre> iz Parsedown – zmanjšano, nikoli izgubljeno. Oznaka pogona parsedown-1.7.4-geshi1 razveljavi stare predpomnilnike.
  • CodeMirror in EasyMDE sta priložena (brez povezave, brez odvisnosti od CDN) – posodobitve so namerne spremembe vtičnika z oznako različice.
  • Površine urejevalnikov so v vsebinski plošči in sledijo receptu za zapolnitev plošče iz datagrid (sestavine 1–3 veljajo za urejevalnike enako).
  • Brez posnemanja urejevalnikov Monaco/VS Code (razdelek 5).

12. Dostopnost in združljivost

  • Celoten pregled: Accessibility (zbrano na enem mestu, tu ni podvojeno).
  • Brez JavaScripta ostane vsak gradnik navadno, v celoti dostopno polje textarea.
  • CodeMirror in EasyMDE sta priložena – združljivost z brskalniki sledi opombam ob izdaji posameznega ponudnika (v tej knjižnici ni posebej preizkušena).

13. Odpravljanje težav

Simptom: codeEditor() ne izriše ničesar (prazen niz), čeprav sta textarea in jezik videti pravilna.

Vzrok: $language vsebuje oznako zunaj sql/php/css/javascript/markdown/html (pazite na velike in male črke – preverjanje je natančno, brez normalizacije).

Rešitev: oznako preverite glede na natančen seznam v razdelku 7.


Simptom: ograjeni blok kode v Markdown ni obarvan.

Vzrok: neznana ali manjkajoča oznaka jezika za tremi krativci (```) ali pa ima predpomnilnik še staro oznako pogona.

Rešitev: oznako jezika preverite glede na seznam GeSHi; ob sumu na zastarel predpomnilnik: oznaka pogona parsedown-1.7.4-geshi1 vsili razveljavitev.


Simptom: pri deljenem urejevalniku HTML manjka orodna vrstica ali pa predogled ostane prazen, čeprav je označevanje v izvorni kodi.

Vzrok: dostavljeni sveženj skriptov je zastarel. lib/exe/js.php datoteke iz scripts/ združi prek /* DOKUWIKI:include */ in svojega predpomnilnika ne opira na njihov čas spremembe – sprememba samo v scripts/htmlsplit.js svežnja torej ne obnovi, brskalnik pa ima poleg tega svojo kopijo pod nespremenjeno oznako tseed.

Rešitev: posodobite čas spremembe datoteke script.js vtičnika (touch) in stran v brskalniku znova naložite brez predpomnilnika (Ctrl+Shift+R). Velja za vsako spremembo v vključeni datoteki s skriptom, ne le za ta gradnik.

14. Sorodne teme

sl/wiki/dwe/wkfluentui/component/editors/start.txt · Zadnja sprememba: uporabnika Wolfgang van der Stille