Bookmarklet finder emneord i V2’s CMS

Illustration: Version2
En stump Javascript i et bogmærke er den nemme (og dovne) måde at sy vores emneords-algoritme ind i Version2's CMS. Sådan gør vi.

På Version2 har vi udviklet en machine learning-algoritme, der kan komme med forslag til emneord i nylavede artikler. I sidste artikel opsatte vi en minimal HTTPS-webserver, som kan forsyne bookmarkletten med bud på emner, givet en artikel.

Læs også: V2 amok i skygge-it: Bookmarklet-SSL-server på netværket med hjemmelavet certifikat

I forrige episode af sagaen beskrev vi ideen således:

Version2-journalisten har en ny, færdigskrevet artikel åben i redigerings-modus i CMS'et, og klikker på bookmarkletten i browserens bogmærkelinje.

Derved sender bookmarkletten overskrifter og artikeltekst til serveren via et ajax-kald. Machine learning-algoritmen gør sit arbejde og returnerer bud på emneord til bookmarkletten, som derefter opmærker emneordene i CMS'ets dialogboks med gul baggrundsfarve.

Så kan journalisten bruge forslagene eller ej, ved at sætte et flueben i en krydsboks - sådan som det ser ud i illustrationen i toppen af denne artikel.

Vi har webserveren oppe at køre, så nu kan vi gå i gang med bookmarkletten. En bookmarklet er en stump Javascript, der kan placeres i et link i et browser-bookmark. På den måde slipper vi for at integrere koden i CMS’et, da bookmarkletten blot ændrer lidt på en dialogboks, som beskrevet ovenfor.

Javascript-udvikling med Firefox og Chrome

Til udvikling af bookmarkletten bruger vi Firefox’ Kladdeblok, som er et minimalistisk Javascript-IDE, der kan findes med ‘burger’-menuen Webudvikler > Kladdeblok (Web Developer > Scratchpad, eller skift+f4.)

Det fungerer godt og kan afvikle en kodestump i det aktuelle faneblads kontekst - altså som om, at scriptet befandt sig inde i selve CMS’ets HTML-side. Bookmarkletten fungerer på samme facon, så vi kan altså forvente samme resultat i den færdige løsning.

Nu skal vi hive overskrifter, også kaldet ‘rubrik’ og ‘manchet’ i jargonen, samt brødteksten ud af CMS’ets tekstfelter.

Det gør vi - som beskrevet i en tidligere artikel - ved at finde tekstfeltets css-selector. Det er et css-udtryk, som peger på en bestemt formateret del af kildekoden. Jeg har mere fidus til Chromes bud end Firefox, så jeg benytter Googles browser til dette formål.

Efter at have efter at have fundet selectoren, kan jeg hive teksten ud af CMS’et med Javascripts document.querySelector-metode, :

var rubrik = document.querySelector("#article-node-form > div > div.form-item.form-type-textfield.form-item-title > #edit-title").value;

Jeg tester kodestumpen ved at putte det ind i Firefox’ kladdeblok, og tilføjer en sætning som printer til konsollen.

var rubrik = document.querySelector("#article-node-form > div > div.form-item.form-type-textfield.form-item-title > #edit-title").value;
console.log(rubrik);

Jeg afvikler kodestumpen med kladdeblokkens menu Eksekver > Kør (Ctrl+R).

Nu åbner jeg CMS-sidens konsol med burger-menuen Webudvikler > Inspektør, og vælger fanen Konsol.

Illustration: Version2

— Og det giver netop teksten i rubrik-feltet. Vi gør det samme med de næste to tekstfelter. Nu ser koden sådan ud:

var rubrik = document.querySelector("#article-node-form > div > div.form-item.form-type-textfield.form-item-title > #edit-title").value;
var manchet = document.querySelector("#edit-field-teaser-da-0-value").value;
var brødtekst = document.querySelector("#edit-field-body-da-0-value").value;

Nu skal vi sende teksten til serveren med ajax, eller XMLHttpRequest-objektet i Javascript, som det hedder officielt.

I vores interimistiske skygge-it kører serveren såmænd bare på min egen pc, der hedder noget i stil med tanias-pc.local på Version2’s interne netværks dns-system - så kan mine kollegers pc’er også finde serveren.

Det ser sådan ud:

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("POST", "https://tanias-pc.local:8000/apps/emneord");
oReq.send("##" + rubrik + "\n##" + manchet + "\n" + brødtekst);

Når vi sender teksten af sted til serveren, sætter vi to havelåger foran overskrifterne. Det er fordi vores machine learning-algoritme bliver bedre, hvis vi skriver overskrifter to gange, før vi udregner de estimater, der udpeger emneordene. På serversiden bliver overskrifterne så doblet, før beregningen af estimater udføres.

I linje nummer to ovenfor sætter vi en callback-handler reqListener, som håndterer svaret fra serveren. Koden for handleren ser sådan ud:

function reqListener () {
  var emneord = this.responseText.split(" ");
  var i = 0;
  while (true) {
    i++;
    var label = document.querySelector("body > div.ui-dialog.ui-widget.ui-widget-content.ui-corner-all.chosen-popup.ui-draggable.ui-resizable > div.chosen-popup.ui-dialog-content.ui-widget-content > div:nth-child(" + i + ") > label");
    if (label === null) break;
    var labelTekst = label.textContent;
    for (var emne of emneord) {
      if (labelTekst.toLowerCase().substring(1, labelTekst.length) === emne.toLowerCase()) {
        label.style.backgroundColor = "Yellow";
      }
    }
  }
}

Serverens svar kommer med kaldet this.responseText i linje to, som blot indeholder de fundne emneords-forslag med blanktegn i mellem. Dem splitter vi op til et array, og så løber vi dialogboksens labels - emneordene - igennem i while-løkken.

Ligesom tidligere har vi ved hjælp af Chrome fundet en css-selector, der peger på vores labels i dialogboksen, som er listet på illustrationen øverst i denne artikel.

Selector-udtrykket indeholder et heltal, der kan bruges til at gennemløbe alle labels i dialogboksen. Hvis vi finder et match mellem et emneord fra serveren og en label, sætter vi baggrundsfarven til gul, med linjen label.style.backgroundColor = "Yellow".

While-løkken 'breaker' når vi ikke kan finde flere labels med selectoren. På den måde er løkken stadig gangbar, hvis antallet og udvalget af labels ændres i fremtiden.

Det sidste skridt består i at lave vores Javascript-kode om til noget, der kan placeres i et HTML-link. Her har vi brugt værktøjet Bookmarklet Crunchinator, som er lige ud af landevejen - vi indsætter koden, trykker på knappen 'Crunch', og så er er et link i bunden, 'Your Bookmarklet', som man kan trække lige op på browserens bogmærkelinje, og så er den ged barberet.

Illustration: Version2

Kodeeksemplet kan downloades fra Google Drive (som kan sige nogle fjollede ting undervejs, men bare tryk 'download.'). Når serveren er oppe og køre, via det medfølgende batch-script, kan en testside kan tilgås med url'en: https://localhost:8000/apps/emneord/test - hvor man kan indsætte tekst fra en Version2-artikel og få bud på emneord.

Hvad fremtiden bringer

Det var et langt, underligt trip, fra en oldgammel matematisk sætning til Version2’s CMS, men nu er vores emneords-algoritme færdig. Det tog en del kode og arbejdstimer, og en bunke dunkel skygge-it, men brudt ned i stykker var det var egentlig ikke så kompliceret endda, alt taget i betragtning.

Min kollega Kristoffer får æren at udføre den såkaldte ‘acceptance test’, som det vist hedder. Han har skrevet en ny artikel. Nu klikker han på bookmarkletten, kigger på de gule forslag til emneord og siger...

»Den er god!«

Py-ha, det var godt at høre.

Eftertankerne melder sig. Der er mange måder, vi kan forbedre vores system på:

Vi kunne flytte server-programmet over på en ‘dedikeret server’, så min pc ikke skal stå åben hele tiden.

Vi kunne lave vores bookmarklet om til en browser-extension, så forslagene til emneord kommer automatisk, når dialogboksen åbnes.

Og vi kunne bruge ‘deep learning’ - neurale netværk - til at forbedre algoritmen med.

Mon ikke vi kigger på nogle af mulighederne i fremtiden - stay tuned, folkens.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Følg forløbet
Kommentarer (0)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Log ind eller Opret konto for at kommentere