• No results found

Länkhantering i ett innehållshanteringssystem för World Wide Web

N/A
N/A
Protected

Academic year: 2021

Share "Länkhantering i ett innehållshanteringssystem för World Wide Web"

Copied!
46
0
0

Loading.... (view fulltext now)

Full text

(1)

Examensarbete

Länkhantering i ett innehållshanteringssystem

för World Wide Web

av

Martin Jonsson

LITH-IDA-EX-ING--07/001--SE

(2)

Rapporttyp Report category Licentiatavhandling Examensarbete C-uppsats D-uppsats Övrig rapport Språk Language Svenska/Swedish Engelska/English Titel Title Författare Author Sammanfattning Abstract ISBN ISRN LITH-IDA-EX-ING--07/001--SE

Serietitel och serienummer ISSN

Title of series, numbering

Nyckelord

Keywords

Datum

Date

URL för elektronisk version

X

Avdelning, institution

Division, department

Institutionen för datavetenskap Department of Computer and Information Science

Länkhantering i ett innehållshanteringssystem för World Wide Web

Martin Jonsson

Denna rapport presenterar design och implementation av ett system för hantering av länkar i ett

innehållshanteringssystem för webben - Roxen CMS. Länkhantering innebär att länkar inom en webbplats lagras i en central databas för att senare kunna uppdateras och behandlas då resurser flyttas, så att länkar alltid hålls aktuella och konsistenta.

Det hela utmynnar i en lösning där länkar i dokument ersätts med länkreferenser, som slås upp mot databasen när dokumentet visas. Design och implementation tar hänsyn till dagens funktionalitet i Roxen CMS.

Länkhantering, innehållshantering, CMS, Web.

2007-02-22

Linköpings universitet

(3)

Examensarbete

Länkhantering i ett innehållshanteringssystem

för World Wide Web

Martin Jonsson

22 februari 2007

LITH-IDA-EX-ING–07/001–SE

Handledare: Jonas Walldén

Examinator: Tommy Olsson

(4)
(5)

Sammanfattning

Denna rapport presenterar design och implementation av ett system för hante-ring av länkar i ett innehållshantehante-ringssystem för webben – Roxen CMS. Länk-hantering innebär att länkar inom en webbplats lagras i en central databas för att senare kunna uppdateras och behandlas då resurser flyttas, så att länkar alltid hålls aktuella och konsistenta.

Det hela utmynnar i en lösning där länkar i dokument ersätts med länk-referenser, som slås upp mot databasen när dokumentet visas. Design och imple-mentation tar hänsyn till dagens funktionalitet i Roxen CMS.

(6)
(7)

Abstract

This thesis presents the design and implementation of a link management system inside a content management system for the World Wide Web – Roxen CMS. Link management means that links within a web site are stored in a central database to enable the possibility for updates and other processing later on, for example when resources are moved within the site. This means that links are kept consistent at all times.

The result is a solution where links in documents are replaced by link refe-rences, which are resolved by the database when the document is shown. The design and implementation takes the current functionality of Roxen CMS into account.

(8)
(9)

Tillkännagivanden

Jag vill tacka Jonas Walldén, min handledare på Roxen Internet Software, för hans stöd och hjälp under design- och implementationsarbetets gång. Jag vill även tacka övriga medarbetare vid Roxen IS för hjälp med inspiration och för deras trevliga bemötande. Dessutom vill jag tacka min examinator, Tommy Olsson, för värdefulla synpunkter på denna rapport.

(10)
(11)

Innehåll

Sammanfattning iii Abstract v Tillkännagivanden vii 1 Inledning 1 1.1 Introduktion . . . 1

1.2 Om Roxen Internet Software . . . 1

2 Bakgrund 3 2.1 Roxen CMS . . . 3 2.2 Problemfrågeställning . . . 3 2.3 XML . . . 4 2.4 XSLT . . . 4 2.5 XPath . . . 5 2.6 RXML . . . 5 2.7 Pike . . . 5 3 Förberedande analys 7 3.1 Möjlig funktionalitet med länkhantering . . . 7

3.2 Faktorer som kan påverka design och implementation . . . 7

3.2.1 Versionshantering . . . 7

3.2.2 Ändringsareor . . . 7

3.2.3 Arbetsareor . . . 8

3.2.4 Flerspråkighet . . . 8

3.2.5 Workflow Paths . . . 8

3.2.6 Tidig eller sen expansion av länkar . . . 8

3.2.7 Konfidentialitet . . . 9

3.2.8 Replikering . . . 9

3.2.9 Filformat utan ändringsmöjlighet . . . 9

3.3 Angreppssätt . . . 9 4 Design 11 4.1 Representation av länkreferenser . . . 11 4.1.1 Konfidentialitetsproblemet . . . 11 4.1.2 XML-representation . . . 12 4.1.3 Länkreferensidentifierare på URL-form . . . 12 4.2 Databasdesign . . . 14

(12)

x INNEHÅLL

5 Implementation 17

5.1 API och integration med Roxen CMS . . . 17

5.1.1 Krokar . . . 18 5.1.2 Cacheberoenden . . . 18 5.2 Implementation . . . 19 5.2.1 Funktionen resolve_reference() . . . 19 5.2.2 Funktionen make_reference() . . . 20 5.2.3 Funktionen get_referring_pages() . . . 20 5.2.4 Funktionen get_refers_to() . . . 21 5.2.5 Funktionen clear_file_from_ea() . . . 21

5.3 Integration med komponenteditorn i Roxen CMS . . . 21

6 Resultat och slutsatser 25 6.1 Resultat . . . 25

6.2 Slutsats . . . 25

6.3 Framtida arbete . . . 25

(13)

Figurer

2.1 Exempel på XML-kod . . . 4

2.2 Enkel XSL-mall för transformering av XML-koden i figur 2.1 . . 4

2.3 Resultat av applicering av mallen i figur 2.2 på XML-koden i figur 2.1 . . . 5

3.1 Illustrering av ändringsareor och vyarea . . . 8

4.1 XML-kod för länkkomponent . . . 12

4.2 XML-kod för länkkomponent med ID-fält . . . 12

4.3 Enkel XSL-mall för transformering av XML-koden i figur 4.1 . . 13

4.4 Enkel XSL-mall för transformering av XML-koden i figur 4.2 . . 13

5.1 SQL-fråga i resolve_reference() . . . 19

5.2 Resultat av efterprocessning av XHTML-kodsnutt . . . 22

5.3 XSLT-kod för länkreferenssubstitution i XHTML . . . 22

(14)
(15)

Tabeller

4.1 Enskilda delar i en länkreferens på URL-form . . . 14

4.2 Databastabellen linkref . . . 15

4.3 Databastabellen uri . . . 15

4.4 Databastabellen pending_moves . . . 15

5.1 Krokar som används av länkhanteraren . . . 19

(16)
(17)

Kapitel 1

Inledning

1.1

Introduktion

Denna rapport syftar till att presentera arbetet med att designa och implemen-tera ett system för länkhantering i ett kommersiellt innehållshanteringssystem för webben, Roxen CMS. Länkhantering innebär att systemet lagrar alla interna länkar, dvs länkar som refererar till filer inom den egna webbplatsen, i en data-bas. Detta ger möjligheten att i efterhand ändra och bearbeta enskilda länkar på ett enkelt sätt.

1.2

Om Roxen Internet Software

Roxen Internet Software i Linköping, ett företag med ca 20 anställda, utveck-lar det marknadsledande innehållshanteringssystemet Roxen CMS1. Produkten bygger på Roxen Webserver, som är fritt tillgänglig och vars källkod är öppen. Roxen CMS är en kommersiell produkt som säljs, ofta tillsammans med support-avtal, till kunder i Sverige och världen.

(18)
(19)

Kapitel 2

Bakgrund

2.1

Roxen CMS

Roxen CMS är ett versionshanterande system, vilket innebär att varje ändring på en sida eller i en fil tilldelas ett versionsnummer och sparas. Detta gör att man enkelt kan återgå till valfri tidigare version av sidan eller filen. Bilder och andra typer av filer kan också lagras och versionshanteras av systemet.

Roxen CMS lagrar sidor i XML-format, som sedan transformeras till XHTML med hjälp av XSLT, vilket ger en tydlig separation av innehåll och layout. Slut-användare (redaktörer) kan enkelt ändra innehållet i sidor via Insite-editorer, vilket innebär att användaren kan se innehållet så som det presenteras externt, med utökningen att alla delar i sidan går att redigera med en enkel knapptryck-ning.

Det mesta av Roxen Webserver och Roxen CMS är skrivet i programspråket Pike (se avsnitt 2.7).

2.2

Problemfrågeställning

I nuvarande version av Roxen CMS kan användare skapa länkar mellan sidor, med hjälp av så kallade komponenter, som är de beståndsdelar som bygger upp en sida i systemet. Varje komponent representeras av några rader XML-kod, osynliga för normalanvändaren, eftersom komponenten representeras grafiskt i Insite-editorn. Vidare finns komponenter som kan innehålla bilder, vilket egent-ligen också är länkar, då de i HTML representeras av <img>-taggar refererande till den bild som ska visas.

Problem uppstår då målet för en absolut referens flyttas (t.ex. ”/news/ index.xml” till ”/news2/index.xml”), då referensen slutar att fungera, medan källfilen kan flyttas runt med bibehållen länkfunktion. För en relativ referens (t.ex. ”../news/index.xml”) å andra sidan, kan referensen fortsätta att funge-ra om både källa och mål flyttas till samma plats. Dock slutar referensen att fungera om antingen källa eller mål flyttas.

För att råda bot på ovanstående problem införs så kallad länkhantering. Länkhantering innebär att alla referenser (länkar) lagras i en central databas med information om källa och mål, som vid filförflyttningar kan modifieras efter behov. Dessutom kan länkhanteraren svara på frågor om relationer mellan

(20)

4 Bakgrund

objekt, exempelvis om vilka sidor som har länkreferenser till en viss, specifice-rad, sida.

2.3

XML

XML, Extensible Markup Language, är ett språk för definition och lagring av data på ett strukturerat sätt i en form som är lättläslig både för människa och dator [1]. XML-dokument har en trädstruktur och kan innehålla, i princip, vilken typ av data som helst. Definitioner av dataelement består av taggar, som i sin tur kan innehålla attribut, vilka kan precisera vilken typ av data elementet innehåller. Tagg, attribut och data utgör tillsammans ett element. I figur 2.1 ges ett exempel på XML, där <innehåll> är toppnivåtagg, <text> är en undernivå-tagg, storlek är ett attribut vars attributvärde är ’2’ och ”Lorem ipsum . . . ” är text-elementets datainnehåll.

<innehåll>

<text storlek="2">

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. </text>

</innehåll>

Figur 2.1: Exempel på XML-kod

2.4

XSLT

XSLT, Extensible Stylesheet Language Transformations är ett språk som i sig bygger på XML och som används för att transformera XML-dokument till nya XML-dokument baserat på de regler som specificeras i XSLT [2]. I websamman-hang används XSLT för att beskriva utseendemallar för XML-dokument, en tillämpning som ger god separation mellan innehåll och utseendespecifikation. XSLT-mallen innehåller då regler för transformeringen av ett XML-dokument till ett XHTML-dokument som kan förstås av en webläsare. Ett exempel på en XSLT-mall för att transformera XML-dokumentet i figur 2.1 till en XHTML-snutt finns i figur 2.2. Resultatet av transformationen finns i figur 2.3.

<xsl:template match="innehåll"> <font> <xsl:attribute name="size"> <xsl:value-of select="storlek"> </xsl:attribute> <xsl:value-of select="text"/> </font> </xsl:template>

(21)

2.5 XPath 5

<font size="2">

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. </font>

Figur 2.3: Resultat av applicering av mallen i figur 2.2 på XML-koden i figur 2.1

2.5

XPath

XPath, XML Path Language, är ett språk som används för att adressera delar av ett XML-dokument. XPath kan även utföra beräkningar, göra strängoperationer eller andra typer av databearbetning genom inbyggda funktioner [3]. Funktio-nerna är av störst intresse för denna rapport, då vissa sådana har lagts till i XPath till förmån för länkhanteringen.

2.6

RXML

RXML, Roxen Macro Language, är ett webbskriptspråk som används för att generera dynamiskt innehåll i Roxen. Språket är byggt på taggar på samma sätt som XML-dokument och är funktionsmässigt jämförbart med ASP1 och

PHP2.

2.7

Pike

Pike är ett objektorienterat programspråk med en syntax som liknar C, fast med ett mer flexibelt typsystem och enklare hantering av strängar och data-strukturer, vilket ger en effektivare programutveckling [4].

1ASP, Active Server Pages, är ett skriptspråk för Microsofts webbserver Internet

Informa-tion Server

2PHP, PHP: Hypertext Preprocessor, är ett skriptspråk med öppen källkod som kan

(22)
(23)

Kapitel 3

Förberedande analys

3.1

Möjlig funktionalitet med länkhantering

Den primära avsikten med länkhantering i Roxen CMS är en proaktiv lösning där länkar automatiskt uppdateras då en resurs flyttas inom webbplatsen. Ut-över detta möjliggörs funktionalitet för att ge användaren ett varningsmed-delande när denne försöker ta bort en fil som finns länkad från en annan sida, och en valmöjlighet att ta bort länkar som refererar till den borttagna sidan.

Vidare är det möjligt att utöka Roxen Webserver för att vidarebefordra för-frågningar från klienter, exempelvis då en besökare använder sig av ett gammalt bokmärke som refererar till en flyttad sida.

3.2

Faktorer som kan påverka design och

implementation

Länkhanteringssystemet behöver ta hänsyn till ett antal faktorer för att fungera korrekt. Dessa faktorer presenteras nedan.

3.2.1

Versionshantering

Roxen CMS är versionshanterande, vilket betyder att vid varje ändring (com-mit) sparas dokumentet i en ny upplaga, och den gamla finns kvar för att använd-aren ska kunna återgå till föregående version om det skulle önskas.

3.2.2

Ändringsareor

I systemet kan användare redigera sidor och dokument i sin egen ändringsarea (även kallad Edit Area). När man är nöjd med sina ändringar kan man välja att publicera dem på den riktiga webbplatsen, i ”vyarean”, (”commit”, ”incheck-ning”), alternativt kasta bort dem (”discard”, ”bortkastning”) om man inte är nöjd. Ändringsareornas förhållande till vyarean illustreras i figur 3.1.

(24)

8 Förberedande analys

Figur 3.1: Illustrering av ändringsareor och vyarea

3.2.3

Arbetsareor

Ett koncept som kallas arbetsareor, Work Areas, gör det möjligt att arbeta med flera instanser av samma webbplats parallellt, för att exempelvis kunna utföra avancerad testning av en externt osynlig kopia av webbplatsen medan originalplatsen behålls intakt.

3.2.4

Flerspråkighet

En sida i Roxen CMS kan finnas för flera olika språk. Översättare kan översätta sidan i ett Workflow-steg (se avsnitt 3.2.5) innan den publiceras på den externt synliga webbplatsen. Länkar eller bildreferenser kan behöva referera till olika destinationer beroende på språk, t.ex. om en bild innehåller text som översätts till flera språk.

3.2.5

Workflow Paths

I systemet kan man publicera sina ändringar internt, utan att de syns på den riktiga webbplatsen, för att få sina ändringar reviderade av någon annan. En sådan osynlig publicering kallas i systemet ”Hidden Commit”. Detta är en del av det system för översättning/revidering m.m. som kallas ”Workflow Paths”. Poängen med detta är just att exempelvis översättare ska kunna översätta sidan till andra språk, eller att en chefredaktör måste godkänna publiceringen innan den syns för externa besökare.

3.2.6

Tidig eller sen expansion av länkar

Roxen CMS lagrar normalt sett data i XML-filer, som sedan transformeras till HTML via XSLT-mallar och RXML. Detta ger en separation av innehåll och utformning. Med länkhantering behöver man lagra någon slags databasreferens till den riktiga länken, fortsättningsvis benämnd ”länkreferens”, i XML-filerna. Dessa slås sedan upp dessa mot databasen strax innan man skickar ut sidan till klienten. Denna uppslagning bör ske någonstans i XSLT- eller RXML-passen.

(25)

3.3 Angreppssätt 9

Det är dock inte helt klart exakt när uppslagningen ska ske. Det kan ske omedelbart, så att övrig mallogik aldrig ens ser länkreferensen, eller så kan det ske så sent som möjligt, så att exempelvis relativa länkar inte pekar fel. I det senare fallet kan det bli problem då mallogik behöver inspektera sökvägar för att ta ett visst beslut, om enbart länkreferensen finns att tillgå.

3.2.7

Konfidentialitet

En viktig faktor att ta med i utformningen av länksystemet är konfidentialitet. Man måste se till att användare inte kan komma åt eller se information de inte är behöriga att se, exempelvis då en klient automatiskt omdirigeras från en länk som har flyttats till en annan plats. Normalt sett sköts sådant med rättighetssystemet (Access Control) i Roxen, men det kan förekomma fall där länken i sig innehåller känslig information. Detta problem behöver beaktas.

3.2.8

Replikering

I Roxensystemet används replikering mellan servrar för att få skalbarhet. En backend-server används för att editera webbplatsen, och ändringar replikeras sedan till frontend-servrar som klienter ansluter till. Länkhanteringssystemet måste kunna replikera sin databas synkroniserat med replikeringen av enskilda sidor, för att inte inkonsistens ska uppstå.

3.2.9

Filformat utan ändringsmöjlighet

Webbplatser kan innehålla dokument som man inte kan eller får ändra i, men som ändå länkar till andra resurser inom webbplatsen. Sådana dokument skulle länksystemet kunna hantera med något försämrad funktionalitet. Då länkrefe-renser inte kan användas går det inte att automatiskt uppdatera länkarna vid behov, men däremot kan länkarna registreras i databasen och användaren kan meddelas att vissa filer behöver uppdateras manuellt vid flytt eller borttagning av dokument.

3.3

Angreppssätt

För att lösa problemet kan ett proaktivt eller reaktivt angreppssätt väljas, eller en kombination. Den proaktiva länkhanteringen kommer att utgöra tyngd-punkten i systemet. Detta innebär länklagring i en databas och uppslagning av länkreferenser då sidan visas. Vid flytt av dokument uppdateras länkar direkt i databasen. En reaktiv lösning kan innebära att en s.k. crawler1 letar igenom webbplatsen efter länkar som inte längre gäller och sedan uppdaterar dem, men detta är troligen både funktionsmässigt sämre och dessutom mer svårimple-menterat jämfört med en proaktiv lösning. En crawler kan eventuellt fylla en funktion för att rapportera trasiga länkar till externa sidor.

1En crawler är ett program som automatiskt bläddrar igenom webbsidor och bearbetar

(26)
(27)

Kapitel 4

Design

4.1

Representation av länkreferenser

Då jag från början presenterades länkhanteringsproblemet tänkte jag mig en lösning där alla sidor efterbearbetas vid varje incheckning och alla länkar sparas i en databas. När sidan sedan efterfrågas av en klient skulle sidan förbearbetas och alla länkar jämföras med databasen och bytas ut mot nyare länkar om sådana existerar.

Efter ett tag insåg jag att det vore bättre att ha någon slags unik identifierare för varje länkreferens1. Detta gör att det går att separera olika länkar som

refe-rerar till samma mål. En lösning som då blev möjlig innebär att varje länk skulle bytas ut mot en mellanform där ett identifikationsnummer representerar länkens mål, exempelvis http://www.exempel.se/linkmanager.pike?id=42 som i sin tur vidarebefordrar förfrågan till http://www.exempel.se/dokument.xml.

4.1.1

Konfidentialitetsproblemet

Problemet med länkar på mellanform är att kravet på konfidentialitet inte auto-matiskt uppfylls, då personer kan gissa sig fram till länkreferens-ID:n, och på så vis få se information som de egentligen inte borde se. Detta kan illustreras med ett exempel: vi låter länkreferens-ID ’42’ referera till:

/nyheter/2007/25-personer-varslas-om-uppsagning.xml

Målsidan kan vara skyddad med rättighetskontroll och bara vara länkad internt, men ändå kan en extern användare genom att gissa ID-numret ’42’ råka få se sidans sökväg och därmed obehörigen få informationen att 25 personer kommer att varslas om uppsägning år 2007.

Konfidentialitetsproblemet kunde lösas genom att länkens ID lagras i källfilen och ID-numret översätts till den riktiga länken precis innan sidan skickas ut till klienten. Denna lösning var särskilt tilltalande då sidbearbetning av XML-filer redan kan göras på ett enkelt sätt med hjälp av XSLT och RXML.

1Med ”länkreferens” avses den entitet som refererar till ett visst mål, exempelvis en sida,

(28)

12 Design <href-component> <link>nyheter.xml</link> <target>_self</target> <description>Nyheter</description> </href-component>

Figur 4.1: XML-kod för länkkomponent

4.1.2

XML-representation

I dagens version av Roxen CMS kan XML-koden för en länkkomponent se ut som i figur 4.1. Länkens mål representeras av <link>-fältet. Med ett fält för länkens ID-nummer tillagt kan koden se ut som i figur 4.2. XSLT-mallen för att transformera XML-koden i figur 4.1 till XHTML kan i en enkel version se ut som i figur 4.3. För att expandera fältet <link-id> i figur 4.2 till en riktig länk behövs någon slags funktion för uppslagning av länk-ID:n mot databasen. Detta kan implementeras genom att lägga till en ny XPath-funktion, se figur 4.4. I Roxen CMS finns redan utökningar till XPath i form av extra funktioner för att exempelvis plocka fram metadata ur vissa filer. Därför verkade det lämpligt att lägga till ytterligare en sådan funktion just för länkuppslagningen, benämnd rxml:resolve-linkref(). <href-component> <link>nyheter.xml</link> <link-id>42</link-id> <target>_self</target> <description>Nyheter</description> </href-component>

Figur 4.2: XML-kod för länkkomponent med ID-fält

Fördelen med att <link>-fältet finns kvar i figur 4.4 är att koden blir bakåt-kompatibel med redigeringseditorn i Roxen CMS, som läser just det fältet. Fältet uppdateras i initieringen av redigeringseditorn och hålls därmed konsistent med databasen. I XSL-mallen kan man dessutom falla tillbaka på <link>-fältet om <link-id>-fältet inte existerar. Detta ger bakåtkompatibilitet för XML-sidor som ännu inte har uppdaterats med länkhantering. Om <link-id>-fältet exi-sterar ignoreras dock <link>-fältet, eftersom det kan innehålla en länk som inte är konsistent med databasen.

4.1.3

Länkreferensidentifierare på URL-form

Efter några veckors programmering och en del konfererande med anställda på Roxen IS insåg jag att det ändå kan vara en fördel att ha länkreferensidentifiere på URL-form (se även [5]), dvs något som liknar den ”mellanform” som beskrivs i avsnitt 4.1. Detta gör att både mellanform och verklig länksökväg kan användas. Fördelen med mellanformen är att länken blir tidspersistent, vilket innebär att den alltid refererar till samma sak, oavsett målets placering i det interna

(29)

fil-4.1 Representation av länkreferenser 13 <xsl:template match="href-component"> <a> <xsl:attribute name="href"> <xsl:value-of select="link"/> </xsl:attribute> <xsl:attribute name="target"> <xsl:value-of select="target"/> </xsl:attribute> <xsl:value-of select="description"/> </a> </xsl:template>

Figur 4.3: Enkel XSL-mall för transformering av XML-koden i figur 4.1

<xsl:template match="href-component"> <a> <xsl:attribute name="href"> <xsl:value-of select="rxml:resolve-linkref(link-id)"/> </xsl:attribute> <xsl:attribute name="target"> <xsl:value-of select="target"/> </xsl:attribute> <xsl:value-of select="description"/> </a> </xsl:template>

Figur 4.4: Enkel XSL-mall för transformering av XML-koden i figur 4.2

systemet, eftersom länkreferensens mål kan slås upp vid själva förfrågan och en vidarebefordran kan göras. Tidspersistenta länkar är nyttiga för exempelvis bok-märken i klientens webläsare, eftersom dessa inte kan uppdateras automatiskt på serverns begäran.

Nackdelen med mellanformen är att man inte omedelbart kan se vad län-ken refererar till, enbart genom att titta på själva URL:en. Därför kan man välja att översätta alla länkar på en sida till deras verkliga representationer (se avsnitt 4.1.2) innan sidan skickas ut till klienten, och därmed kan användaren omedelbart se vad länken refererar till när denne t.ex. drar muspekaren över länken.

När man betraktar länkar på mellanform uppstår återigen frågan om kon-fidentialitetsproblemet (se avsnitt 4.1.1). Problemet med gissade länkreferens-ID:n kan dock lösas genom att man gör länkidentifieraren så lång att sannolik-heten att någon skulle lyckas gissa sig till ett giltigt ID blir extremt låg.

(30)

14 Design

länkar i databasen är 1.000.000 gäller att sannolikheten P (giltig) för att en person ska gissa ett giltigt ID på ett enda försök är:

P (giltig) = 10 6 2160 < 220 2160 ⇔ P (giltig) < 2−20· 220 2−20· 2160 ⇔ P (giltig) < 1 2140

Det tar alltså, i genomsnitt, fler än 2140 försök att gissa sig till ett giltigt ID

då en miljon länkar finns lagrade i databasen. Som jämförelse kan nämnas att 2140> 1.3 · 1042.

160 bitar kan representeras av 20 tecken om en byte vardera (8 bitar är en byte och 1608 = 20), men eftersom många tecken är otillåtna i URL:er reducerar vi talbasen från 256 (8 bitar per tecken) till 36 som kan representeras av tecknen a-z samt 0-9, vilket ger en stränglängd om maximalt 31 tecken.

Utformning av länkreferens på URL-form

Länkreferensen på URL-form föreslås se ut som (ID-delen är något förkortad av utrymmesskäl):

http://www.server.se/.linkref/8yspa1kkgr2...p872zf8bg9u/house.jpg I tabell 4.1 visas de olika delarna i ovanstående URL. ”Serveradress” är adres-sen till den server som kör Roxen CMS. ”Fördefinierad sträng” är en textsträng som talar om för servern att det rör sig om en länkreferensförfrågan och att för-frågan därför ska behandlas på ett speciellt sätt. ”Länkreferens-ID” är den 160 bitar långa länkreferensidentifierare som diskuterats ovan. ”Filnamn” är slutligen filnamnet på målobjektet som det såg ut då servern skickade ut URL:en till kli-enten. Detta filnamn är oväsentligt för förfrågan, men gör att ett mer deskriptivt filnamn syns i exempelvis nedladdningsrutor samt att det tillfredsställer webb-läsare som litar mer på filnamn än på protokollhuvudet Content-Type: i HTTP.

http://www.server.se/ Serveradress

.linkref/ Fördefinierad sträng 8yspa1kkgr260ukzlj51p872zf8bg9u/ Länkreferens-ID

house.jpg Filnamn

Tabell 4.1: Enskilda delar i en länkreferens på URL-form

4.2

Databasdesign

Databasens utformning utvecklades under implementationsarbetets gång och var inte huggen i sten från början, men här kommer enbart den slutgiltiga utformningen att visas. I tabell 4.2 beskrivs databastabellen linkref, som är huvudtabellen. source_component används för att referera till den komponent där länkreferensen ligger, vilket gör att man exempelvis kan ta bort de kompo-nenter som refererar till en viss sida. user_id används för att beskriva vilken ändringsarea (se avsnitt 3.2.2) länken finns i. first_rev och last_rev används för att beskriva vilken som var den första respektive sista revisionen av käll-sidan där länkreferensen existerade. Dessa behövs för att senare kunna återgå till en tidigare revision av en sida med bibehållen databaskonsistens. latest,

(31)

4.2 Databasdesign 15

Fältnamn Typ Beskrivning id int(11) Primärnyckel link_id varchar(255) Länkreferens-ID

source_uri int(11) Länkreferensens källsida dest_uri int(11) Länkreferensens destination source_component varchar(50) Källkomponent

user_id int(11) Användar-ID language char(2) Källsidans språk

latest tinyint(1) Senaste revisionen? published tinyint(1) Externt synlig?

dirty tinyint(1) Ändrad sedan senaste replikering? first_rev varchar(16) Källsidans första revision

last_rev varchar(16) Källsidans senaste revision Tabell 4.2: Databastabellen linkref

published och dirty är booleska fält som indikerar om länken existerar i den senaste revisionen av källsidan eller ej, om länken är externt synlig respektive om raden har uppdaterats sedan senaste replikeringstillfället. source_uri och dest_uri är främmande nycklar till id-fältet i databastabellen uri.

Databastabellen uri (se tabell 4.3) innehåller mängden av unika sökvägar till samtliga källor och mål.

Databastabellen pending_moves (se tabell 4.4) innehåller källsökväg och målsökväg för objekt som flyttas av användare i ändringsareor, där user_id representerar ändringsareanumret. Eftersom man inte vill att publikt synliga länkar ska uppdateras förrän flytten verkligen är incheckad, mellanlagras flyt-ten i denna tabell och publika länkar uppdateras först när användaren trycker ”Commit” på det flyttade objektet.

Fältnamn Typ id int(11) uri blob dirty tinyint(1) Tabell 4.3: Databastabellen uri

Fältnamn Typ id int(11) from_uri int(11) to_uri int(11) user_id int(11)

(32)
(33)

Kapitel 5

Implementation

5.1

API och integration med Roxen CMS

Länkhanteringens API, Application Programming Interface, består av fem huvud-sakliga funktioner:

string

resolve_reference(string refurl, RequestID id, void|int userid)

string

make_reference(string source, string dest, RequestID id, string curref, void|string source_component)

array(mapping(string:string))

get_referring_pages(string page_uri, RequestID id, void|int userid)

array(string)

get_refers_to(string page_uri, RequestID id, void|int userid)

void clear_file_from_ea(SBObject sbobj, void|string lang)

resolve_reference() är den funktion som översätter länkreferenser till verk-liga sökvägar/länkar. Parametern refurl ska innehålla en länkreferens på URL-form. id är ett internt Roxen-objekt som används för att lagra olika parametrar och variabler som hör till ett visst anrop – i funktionen används det dels för att läsa ut arbetsareans monteringspunkt, så att den resulterande sökvägen pekar rätt, och dels för att registrera ett cacheberoende på denna länkreferens. Läs mer om cacheberoenden i avsnitt 5.1.2. Parametern userid, slutligen, ska innehålla användar-ID för den ändringsarea där länken slås upp, då samma länkreferens kan referera till olika saker i olika ändringsareor. Om vyarean, den publikt syn-liga ”ändringsarean”, avses ska userid vara satt till 0. Funktionen returnerar en sträng som innehåller den uppslagna URI:n.

make_reference() används för att skapa en ny länkreferens. source och dest är parametrar för källsidans sökväg respektive målets URI. id är det interna Roxen-objekt som beskrivs ovan. curref är en existerande länkreferens om en sådan finns. Länkhanteraren försöker återanvända denna referens om

(34)

18 Implementation

möjligt, och uppdaterar då målets URI. Om det inte är möjligt att återanvända länkreferensen, på grund av att samma referens finns på flera sidor som ett resultat av t.ex. en sidkopiering, skapas en ny länkreferens. source_component är en valfri parameter som kan innehålla en ID-sträng för den komponent som länkreferensen finns i, dvs samma fält som beskrivs i avsnitt 4.2.

get_referring_pages() returnerar källside-URI, länkreferens och källkomp-onent-ID för alla länkreferenser som refererar till det mål som specificeras i para-metern page_uri. Om userid specificeras returneras detsamma fast för alla länkar som finns i en användares ändringsarea. Denna funktion kan exempelvis användas för att visa användaren vilka länkar som kommer att sluta fungera om ett visst objekt tas bort.

get_refers_to() returnerar mål-URI, länkreferens och källkomponent-ID för alla länkreferenser som finns på sidan som specificeras i parametern page_uri. Om userid specificeras görs förfrågan för en viss användares ändringsarea.

clear_file_from_ea() tar bort alla länkreferenser för en viss källsida i en viss ändringsarea, för ett visst språk om parametern lang är specificerad. Parametern sbobj används för att plocka fram vilken fil och vyarea som avses.

5.1.1

Krokar

Då Roxen CMS i grunden är ett modulärt system finns bra stöd för att kommu-nicera med övriga delar i systemet. Ett koncept för sådan kommunikation som används i systemet kallas ”hooks”, krokar. Det innebär att en modul kan kroka in vissa funktioner som kommer att köras i samband med att andra händelser inträffar i systemet, till exempel ”Commit”. Commit innebär att en användare ”publicerar” den sida som finns i dennes ändringsarea, och därmed ska länk-referensinformation överföras från ändringsarean till vyarean. Detta görs med hjälp av en commit hook som uppdaterar lämpliga rader i databasen. Andra krokar som används av länkhanteraren beskrivs i tabell 5.1.

5.1.2

Cacheberoenden

I Roxen CMS används olika typer av cache för att förbättra prestandan. Exempel-vis kan resultatet av en XSLT-transformering av en sida lagras i cache, för att slippa göra transformeringen vid nästa förfrågan, och därmed spara processor-kraft. Cachen för en sida måste dock invalideras och kastas bort om en ändring sker i ursprungssidan för att inte inaktuell data ska skickas ut till klienter. Detta sker genom s.k. notifieringar.

Länkhanteringssystemet registrerar cacheberoenden för en viss sida, på alla länkreferenser som finns på sidan, vilket sker när länkreferenserna slås upp, i resolve_reference(). När sedan en filförflyttning medför att länkreferenser upp-dateras kommer cachesystemet att notifieras om att en ändring har skett och cachen invalideras. Notifieringen sker i direkt anslutning till att databasen upp-dateras.

(35)

5.2 Implementation 19

Krok Beskrivning

commit_edit Överför länkreferenser från användarens ändringsarea till vyarean (huvudarean).

commit_update Uppdaterar länkreferenser till objekt i ändringsareor som flyttats och som nu checkas in i vyarean. (Läs även om pending_moves i avsnitt 4.2)

commit_delete Sätter publicerad-flaggan till 0 för den berörda filen. revert Lägger in länkreferenser, från den revision man återgår till,

i användarens ändringsarea.

discard Tar bort länkreferenser från användarens ändringsarea för den sida som kastas bort.

copy Duplicerar alla länkreferenser för den sida som kopieras. move Lägger in information om att en sida flyttats i

databas-tabellen pending_moves (se även avsnitt 4.2). Anropar även copy-kroken för att duplicera länkreferensen.

purge Rensar bort alla länkreferenser ur databasen för den käll-sida som kastas bort för alltid (purge).

set_metadata Inspekterar metadataändringar och kontrollerar om språk har lagts till eller tagits bort för en sida och duplicerar länkreferenser vid behov.

Tabell 5.1: Krokar som används av länkhanteraren

5.2

Implementation

5.2.1

Funktionen resolve_reference()

resolve_reference() plockar först ut länkreferensens ID-nummer ur den kom-pletta URL:en med en hjälpfunktion (se avsnitt 4.1.3). Sedan ställs en SQL-fråga mot databasen som tar fram rätt destination ur huvudtabellen och genom en join med tabellen för väntande förflyttningar ser man till att länkar alltid pekar rätt även inom ändringsareor. SQL-frågan som används kan ses i figur 5.1.

SELECT uritbl.uri AS dest, lreftbl.id

FROM uri_main AS uritbl, lref_main AS lreftbl LEFT JOIN pending_moves_main AS mvtbl

ON mvtbl.from_uri=lreftbl.dest_uri AND mvtbl.user_id=2 WHERE lreftbl.link_id=’kle3gpmnrxqe5jqax42duwpgh94c6px’ AND (lreftbl.user_id=2 OR lreftbl.user_id=0)

AND uritbl.id=IFNULL(mvtbl.to_uri, lreftbl.dest_uri) ORDER BY lreftbl.user_id DESC LIMIT 1

Figur 5.1: SQL-fråga i resolve_reference()

Genom att sortera på användar-ID i fallande ordning och med LIMIT 1 garanteras att man får destinationen som den ser ut i ändringsarean i första hand, och om den inte existerar där får man vy-varianten, då den har användar-ID 0.

(36)

20 Implementation

5.2.2

Funktionen make_reference()

make_reference() läser först ut användar-ID och språk ur id -objektet. Sedan normaliseras sökvägen för att få en sökväg inom en arbetsarea, Work Area. En arbetsarea kan monteras på t.ex. ”/sweden/” och om ”/sweden/nyheter/ index.xml” normaliseras fås ”nyheter/index.xml” som resultat. Det finns en länk-hanteringsdatabas för varje arbetsarea.

Därefter läggs källa och mål in i URI-tabellen, om de inte redan existerar, och id-numren sparas i variabler. Om anroparen har skickat med parametern curref, ”current reference”, jämförs den med källa, destination och språk i data-basen för att se om länkreferensen ska fortsätta peka på samma sak. Om så är fallet uppdateras endast revisionsnumret i databasen, annars skapas en ny länkreferens.

Vid kopieringar och dylika operationer kommer alla länkreferenser för den kopierade sidan att dupliceras i databasen av någon av de krokar som finns, och på så vis kan man detektera om flera sidor eller flera språk delar samma länk-referens. I så fall kan inte den länkreferensen ändras, eftersom det skulle resultera i att länkar på flera sidor ändras, vilket förmodligen inte är vad användaren avsåg.

När alla värden finns på plats i databasen konstrueras en länkreferens på URL-form utifrån serverns adress, arbetsareans monteringspunkt, länk-ID och destinationsfilens namn, som returneras till anroparen. (Se även avsnitt 4.1.3).

5.2.3

Funktionen get_referring_pages()

get_referring_pages() börjar med att fråga dir_module efter alla indexfiler, t.ex. index.html, index.xml och liknande. Dessa jämförs med den måladress som har givits som parameter. Om adressen slutar med en indexfil tas indexfilen bort från adressen och resultatet läggs till i listan över måladresser som ska undersökas. Detta gör att man får ett mer intuitivt resultat om en länkreferens pekar på exempelvis /news/ och API-anroparen har bett att få alla referenser som pekar på /news/index.xml, om index.xml är en indexfil. Exempel på hur listan av mål byggs finns i tabell 5.2.

Inparameter Indexfiler Resultat /news/ index.xml index.html /news/ /news/index.xml /news/index.html /news/index.xml index.xml index.html /news/index.xml /news/

Tabell 5.2: Exempel, indexfilers inverkan på undersökta måladresser

En fråga ställs mot databasen för varje måladress som konstruerats för att ta fram alla källadresser som refererar till just den måladressen. Ett villkor används för att bara få tillbaka de länkreferenser som existerar i den senaste revisionen av en sida, eftersom man inte vill se länkereferenser som har tagits bort i tidigare revisioner.

Om parametern userid har givits till funktionen jämförs resultatet av data-basfrågan med användarens ändringsarea (också genom en databasfråga), och

(37)

5.3 Integration med komponenteditorn i Roxen CMS 21

om en länkreferens pekar på något annat där, tas den bort från listan, då använd-aren inte vill se referenser som har tagits bort i ändringsarean.

Slutligen läggs nya länkreferenser från användarens ändringsarea till, och resultatet snyggas till och returneras.

5.2.4

Funktionen get_refers_to()

get_refers_to() fungerar på ungefär samma sätt som get_referring_pages(), med undantaget att några extra sökvägar inte behöver byggas; först tas alla länkreferenser fram för vyarean, vilka sedan jämförs med ändringsarean om userid är skilt från 0. Länkreferenser som skiljer sig plockas bort och nya sätts in.

5.2.5

Funktionen clear_file_from_ea()

clear_file_from_ea() ställer en enda SQL-fråga som tar bort alla länkrefer-enser för den specificerade källsidan i den specificerade ändringsarean.

5.3

Integration med komponenteditorn i Roxen

CMS

Normalt sett utgörs sidor i Roxen CMS av komponenter (som beskrivet i avsnitt 2.2). Komponenter är plugins till komponenteditorn (vars användargränssnitt är avbildat i figur 5.4), vilket gör att det enkelt går att införa nya komponentplugins i efterhand. Koden för varje plugin beskriver hur komponenten ska ritas upp i editorn, vilka variabler som ska sparas och vad som ska hända när editorn stängs, bland annat. Detta kan utnyttjas för att koppla in länkhanteringen för olika komponenter.

I komponentfunktionen notify_close(), som anropas när editorn stängs, lägger man in ett anrop till länkhanterarens make_reference() för att få till-baka en länkreferens som sedan sparas i ett nytt XML-fält (för ytterligare beskrivning av XML-representationen av komponenter, se avsnitt 4.1.2). Om en länkreferens redan existerar matas det in som parameter till make_reference() som provar om samma länkreferens går att återanvända.

I komponentfunktionen render_editor(), som anropas när komponenten ska rita upp sig själv, anropar vi länkhanterarens resolve_reference() för att slå upp länkreferensen som sparades av notify_close() till en verklig URI. Resultatet läggs in i det fält editorn normalt läser av och ritar upp. Detta gör det enkelt att uppgradera komponenter för att använda sig av länkhantering.

Beskrivningen för hur länkar och bilder presenteras i komponenteditorn finns i XSLT-mallar, och XPath-funktionen rxml:linkresolve() används för att slå upp länkreferenserna till verkliga länkar (se även avsnitt 4.1.2) för varje icke-cachat anrop, vilket gör att länkens destination hålls aktuell.

Komponenteditorn ger dessutom användaren möjlighet att editera sidfrag-ment i ett lite mer fritt läge, genom att använda en XHTML-texteditor benämnd FCKeditor1. FCKeditor matar ut XHTML-kod där länkar kan förekomma var

(38)

22 Implementation

som helst i i texten. Genom viss för- och efterprocessning av denna XHTML-kod kan man införa stöd för länkhantering även här.

I efterprocessningen letar man upp alla <a>-taggar och plockar ut href-attributet, som matas in i make_reference(). Resultatet blir en länkreferens som sparas i ett nytt attribut vid namn ”lref”. Detta attribut matas även in som parameter till make_reference() om attributet redan existerar, för eventuell återanvändning. Den resulterande kodsnutten kan se ut som i figur 5.2 (extra radbrytningar har satts in av utrymmesskäl).

<a href=’/news/’

lref=’http://www.server.se/.linkref/ h2z0zxoaqf2vuol7yhykdegl6sx2c1w/’ target=’_self’>News</a>

Figur 5.2: Resultat av efterprocessning av XHTML-kodsnutt

När texteditorn senare återöppnas görs en förprocessning av XHTML-koden, och lref-attribut i <a>-taggar slås upp med hjälp av resolve_reference(). Resultatet sätts in i href-attributet som sedan används av texteditorn (FCK-editor). Detta gör att användaren kan arbeta med aktuella länkar.

Vid sidvisning slås länkreferensen upp och stoppas in i href-attributet, medan lref-attributet tvättas bort. Detta sker med hjälp av XSLT-kodsnutten i figur 5.3.

<xsl:template match="a | A"> <a> <xsl:copy-of select="@*[name(.)!=’lref’]" /> <xsl:attribute name="href"> <xsl:value-of select="rxml:linkresolve(@lref)" /> </xsl:attribute> <xsl:value-of select="." /> </a> </xsl:template>

(39)

5.3 Integration med komponenteditorn i Roxen CMS 23

(40)
(41)

Kapitel 6

Resultat och slutsatser

6.1

Resultat

Målet med denna rapport var att designa och implementera ett system för länk-hantering i Roxen CMS, och implementationen tillsammans med denna rap-port utgör resultatet. Designen tar hänsyn till alla faktorer i avsnitt 3.2, och implementationen har testats mot densamma med godkänt resultat förutom mot filformat utan ändringsmöjlighet och mot replikeringssystemet. Databasdefini-tionerna återfinns i bilaga A. Pike-implementationens källkod bifogas ej denna rapport av upphovsrättsskäl.

6.2

Slutsats

Länkhanteringssystemet, som beskrivet i avsnitt 2.2 har designats, implemente-rats och testats för att så enkelt som möjligt kunna integreras med nuvarande version av Roxen CMS. Integration med komponenteditor och texteditor har genomförts med godkänt resultat. Utökningar har gjorts i XPath och RXML för att uppfylla behov av att utföra förfrågningar mot länkhanteraren på en hög abstraktionsnivå, där slutanvändare är inblandade. Designen har växt fram allt eftersom implementationsarbetet har fortskridit, och bedöms uppfylla alla förutsägbara krav som finns på länkhanteringen.

6.3

Framtida arbete

För att fullständigt integreras med Roxen CMS behöver länkhanteringssystemet tillhandahålla funktioner för replikering av databasposter, synkroniserat med replikeringen av filer, för att uppnå fullständig konsistens och länkintegritet. Sådan funktionalitet har endast påbörjats i nuvarande implementation.

Vidare bör stöd för filformat utan ändringsmöjlighet fullständigt utvärde-ras, implementeras och testas. Eventuellt kan förtolkning av Cascading Style Sheet (CSS) och XSLT-mallar införas för att kunna utnyttja fördelarna med länkhantering även för dessa typer av filer.

(42)
(43)

Litteraturförteckning

[1] T. Bray, J. Paoli, C. M. Sperberg-McQueen, E. Maler, F. Yergeau, J. Cowan Extensible Markup Language (XML) 1.1, W3C Recommendation. Andra utgåvan. World Wide Web Consortium. 16 augusti 2006. (Nedladdad 6 no-vember 2006 från http://www.w3.org/TR/2006/REC-xml11-20060816/). [2] J. Clark XSL Transformations (XSLT) 1.0, W3C Recommendation. World

Wide Web Consortium. 16 november 1999. (Nedladdad 6 november 2006 från http://www.w3.org/TR/1999/REC-xslt-19991116).

[3] J. Clark, S. DeRose XML Path Language (XPath) 1.0, W3C Recommen-dation. World Wide Web Consortium. 16 november 1999. (Nedladdad 7 november 2006 från http://www.w3.org/TR/1999/REC-xpath-19991116). [4] H. W. Welliver, M. Bähr Pike: an Introduction. The Pike Development

Team. 2006.

[5] T. Berners-Lee, R. Fielding, U. C. Irvine, L. Masinter Uniform Resource Identifiers (URI): Generic Syntax. RFC 2396. Network Working Group. Augusti 1998. (Nedladdad 7 november 2006 från http://www.ietf.org/rfc/rfc2396.txt).

[6] The Pike Development Team Module reference for Pike v7.6. Utgåva 86. 12 juli 2006. (Använd under hela implementationsarbetet, nedladdad från http://pike.ida.liu.se/generated/manual/modref/).

(44)
(45)

Bilaga A

(46)

30 Databasdefinitioner i SQL

---- Table structure for table ‘linkref_main‘

--DROP TABLE IF EXISTS ‘linkref_main‘; CREATE TABLE ‘linkref_main‘ (

‘id‘ int(11) NOT NULL auto_increment, ‘link_id‘ varchar(255) NOT NULL default ’’, ‘source_uri‘ int(11) default NULL,

‘dest_uri‘ int(11) default NULL,

‘source_component‘ varchar(50) default ’’, ‘user_id‘ int(11) default ’0’,

‘language‘ char(2) default ’’, ‘latest‘ tinyint(1) default ’0’, ‘published‘ tinyint(1) default ’0’, ‘dirty‘ tinyint(1) default ’0’, ‘first_rev‘ varchar(16) default NULL, ‘last_rev‘ varchar(16) default NULL, PRIMARY KEY (‘id‘),

KEY ‘source_uri_index‘ (‘source_uri‘), KEY ‘link_id_index‘ (‘link_id‘(8)) ) TYPE=MyISAM;

---- Table structure for table ‘pending_moves_main‘

--DROP TABLE IF EXISTS ‘pending_moves_main‘; CREATE TABLE ‘pending_moves_main‘ (

‘id‘ int(11) NOT NULL auto_increment, ‘from_uri‘ int(11) default NULL, ‘to_uri‘ int(11) default NULL, ‘user_id‘ int(11) default NULL, PRIMARY KEY (‘id‘)

) TYPE=MyISAM;

---- Table structure for table ‘uri_main‘

--DROP TABLE IF EXISTS ‘uri_main‘; CREATE TABLE ‘uri_main‘ (

‘id‘ int(11) NOT NULL auto_increment, ‘uri‘ blob,

‘dirty‘ tinyint(1) default ’0’, PRIMARY KEY (‘id‘),

UNIQUE KEY ‘uri‘ (‘uri‘(32)) ) TYPE=MyISAM;

References

Related documents

Adress 103 85 Stockholm Besbksadress Ringviigen 100 Tele/on 08-7001600 konkurrensverket@kkv.se.

handläggningen har också föredragande vej amhetsanalytiker Peter Vikström

J an-Olof Olsson har varit

Dessutom har utbyggnaden av förnybar elproduktion fortgått vilket leder till att det är än mer sannolikt än tidigare att målet om totalt 46,4 TWh förnybar elproduktion till

Först ut till fruktdiskarna är Royal Gala, en av de 13 sorterna i Sydtyrolen som sedan 2005 bär den skyddade geografiska beteckningen Südtiroler Apfel SGB.. I slutet av augusti

Since the last five chapters in each textbook of World Wide English are adapted to appeal to social science or natural science students one can argue that the material coheres

Keywords: Craft, jewellery, situated making, noticing, care, empathy, postindustrial, world wide workshop.. ISBN: 978-91-7833-610-4 (printed version) ISBN: 978-91-7833-611-1

Faktorerna som påverkar hur lätt vagnen är att manövrera är vikten, val av hjul och storleken på vagnen. Val av material påverkar vikten i stor utsträckning och då vagnen ska