Del 4: Innholdsarkitektur – riktig struktur gjør alt annet enklere

Del 4 av 12 i serien «Jeg bygde en komplett medlemskapsplattform i WordPress.»


De fleste begynner med innhold.

De oppretter en side, skriver tekst, legger til bilder, publiserer. Så kommer neste side. Og den neste. Etter hvert er det mange sider, og strukturen som aldri ble bestemt begynner å vise seg som problemer: duplikat-innhold i arkiver, tilgangskontroll som ikke skalerer, søk som returnerer feil ting, navigasjon som ingen forstår.

Jeg begynte med datamodellen.

Ikke fordi det er morsommere enn å skrive innhold (det er det ikke) men fordi feil datamodell er teknisk gjeld som bare vokser. Riktig modell gjør navigasjon, søk, tilgangskontroll og arkivsider til løste problemer.

Tre innholdstyper – og hvorfor de er forskjellige

Din Plattform er bygget rundt tre distinkte innholdstyper. Hver har sin egen metadata, sine egne regler og sin egen mal. De er ikke varianter av det samme – de gjør fundamentalt forskjellige ting.

Bloggposter er den åpne inngangsporten. De er kortere, mer rett frem, og handler om ett tema av gangen. Metadata her er enkel: lesetid, en featured-flagg for fremhevede poster, og tilgangsnivå (gratis, Insider eller Premium).

Magasinartikler er organisert i numre – issues. Hvert nummer har et omslag, en publiseringsdato, en featured-flagg og redaktørens ord. Artiklene innenfor nummeret har posisjonsnummer, lesetid, excerpt og en kobling tilbake til nummeret de tilhører. Den koblingen er det som gjør at innholdsfortegnelsen for et nummer kan hentes dynamisk: «gi meg alle artikler der issue-feltet peker til dette nummeret, sortert på posisjonsnummer».

Leksjoner er knyttet til kurs via en taxonomi. En leksjon vet hvilket kurs den tilhører, hvilken posisjon den har, om den inneholder video, og om den er låst bak drip-feed – altså om den tidsforskyves basert på når medlemmet startet kurset.

Tre typer. Tre forskjellige strukturer. Ingenting av dette ville fungert med standard WordPress-poster og noen kategorier.

MetaBox fremfor ACF – og hvorfor

Det er to dominerende feltramverk for WordPress: Advanced Custom Fields (ACF) og MetaBox. Begge lar deg registrere egendefinerte felt på posttyper og taksonomier.

ACF er det mest kjente. Det er av den grunn ikke nødvendigvis det beste valget.

MetaBox ble valgt av tre grunner. For det første registrerer det Custom Post Types, taksonomier og felt i samme plugin – du trenger ikke ett plugin for CPT-registrering og et annet for felt. For det andre er kodebasen renere og mer utviklervennlig, med sterkere støtte for PHP-basert registrering. For det tredje er ytelsen bedre på store datamengder.

I praksis bor hele innholdsarkitekturen i tre PHP-filer i inc/-mappen:

FilHva den registrerer
post-types-posts.phpFelt på standard bloggposter
post-types-magazine.phpdp_magazine_issue CPT, dp_magazine_article CPT, dp_magazine_tag taksonomi
post-types-lessons.phpdp_lesson CPT, dp_course taksonomi

Endrer du strukturen, er det én fil å oppdatere. Ingenting er spredt rundt i databasen som bare pluginen kjenner til.

Magasinstrukturen – issues, artikler og relasjon

Magasinet er den delen av plattformen med mest kompleks datastruktur. Et nummer (dp_magazine_issue) er en selvstendig enhet med eget omslag, publiseringsdato og redaktørens ord. Artiklene (dp_magazine_article) er separate posttyper som peker tilbake på nummeret de tilhører via et post-select-felt.

Relasjonen ser slik ut:

Magasinnummer (Nr. 3)
  ├── Artikkel (posisjon 01) → tilhører Nr. 3
  ├── Artikkel (posisjon 02) → tilhører Nr. 3
  └── Artikkel (posisjon 03) → tilhører Nr. 3

Innholdsfortegnelsen for et nummer spør: «gi meg alle artikler der issue-feltet peker til dette nummeret, sortert på posisjonsnummer». Det er en enkel databasespørring som alltid returnerer riktig svar – fordi relasjonen er eksplisitt definert i datamodellen, ikke utledet fra kategorier eller slug-mønstre.

Nummereringsformat var en beslutning som krevde litt tenkning: sekvensielt (Nr. 1, 2, 3) eller årsbasert (2024:01, 2024:02)? Årsbasert ble valgt. Det gir en enklere oversikt og er enklere å referere til.

Minikurser – leksjoner, drip-feed og kurskoblinger

Leksjoner er knyttet til kurs via en taksonomi (dp_course), ikke via en parent-post-relasjon. Det gir mer fleksibilitet: taksonomien kan ha egne felt, som tilgangsnivå og drip-feed-konfigurasjon per kurs.

Hver leksjon har et leksjonsnummer (for navigasjon og sortering), en videoindikator (om leksjonen inneholder video), en introduksjonstekst og et repeater-felt for key takeaways.

Drip-feed fungerer på kursnivå: et felt på dp_course-taksonomien definerer antall dager mellom kursets startdato og den dato leksjonen låses opp. Dag 0 betyr umiddelbar tilgang. Dag 7 betyr at leksjonen er tilgjengelig én uke etter at medlemmet startet kurset.

Det er enklere enn det høres ut, og det er robust nok for de aller fleste kursoppsett.

Hva riktig datamodell faktisk gir deg

En datamodell er ikke synlig for brukerne. Den er ikke noe du viser frem på en porteføljeside. Men den er det som bestemmer om funksjonene du vil ha er enkle eller umulige å bygge.

Med riktig struktur på plass er arkivsider en spørring. Tilgangskontroll er ett felt. Søk returnerer riktig innhold. Navigasjon mellom leksjoner er automatisk.

Det er ikke magi. Det er konsekvensen av å ta de riktige beslutningene tidlig.


Neste del: Blokkbiblioteket – hvordan 56 egendefinerte Blockstudio-blokker erstatter en page builder.

Did you like this article? Share it with a friend!