URL rewrite en htaccess
Hallo,
Ik ben voor een site bezig met het verbeteren van de SEO. Nou wil ik graag de URL verbeteren door middel van tekst in plaats van id's in de URL.
Voorbeeld: www.domein.nl/pagina/?id=1&pagina=functie&jaar=2019
ID 1 is bijvoorbeeld jan-peter-balkenende. En ik zou dan de URL willen wijzigen in: www.domein.nl/pagina/jan-peter-balkenende/functie/2019. Ik had alleen een paar vragen die bij me op komen.
- Moet ik dan in de database voor elke persoon een unieke URL-naam opslaan zoals ID 1 = jan-peter-balkenende? Of wat is hierbij gebruikelijk? En dan in plaats van zoeken op ID 1 zoeken op jan-peter-balkenende?
- Is er een mogelijkheid waarbij de oude URL blijft werken? Die staan nu namelijk op Google. Blijven die zo bruikbaar, of kan ik die dan op één of andere manier verwijzen?
Ik ben voor een site bezig met het verbeteren van de SEO. Nou wil ik graag de URL verbeteren door middel van tekst in plaats van id's in de URL.
Voorbeeld: www.domein.nl/pagina/?id=1&pagina=functie&jaar=2019
ID 1 is bijvoorbeeld jan-peter-balkenende. En ik zou dan de URL willen wijzigen in: www.domein.nl/pagina/jan-peter-balkenende/functie/2019. Ik had alleen een paar vragen die bij me op komen.
- Moet ik dan in de database voor elke persoon een unieke URL-naam opslaan zoals ID 1 = jan-peter-balkenende? Of wat is hierbij gebruikelijk? En dan in plaats van zoeken op ID 1 zoeken op jan-peter-balkenende?
- Is er een mogelijkheid waarbij de oude URL blijft werken? Die staan nu namelijk op Google. Blijven die zo bruikbaar, of kan ik die dan op één of andere manier verwijzen?
Ikzelf genereer de slug met de titel direct vanuit de database, en voeg die toe aan de URL, waarbij ik ook de ID apart meegeef.
Dan krijg je dus een URL zoals: www.website.nl/nieuws/5/nieuwe-website-geintroduceerd.html
Hierbij kijk verplicht ik de slug overigens niet, en is deze ook niet de sleutel in de URL. Als iemand de slug in de URL aanpast, dan laat ik een redirect uitvoeren naar de juiste slug:
www.website.nl/nieuws/5/nieuwe-website-geintroduceerd-bla-die-bla.html
komt weer uit op:
www.website.nl/nieuws/5/nieuwe-website-geintroduceerd.html
Omdat de slug niet de sleutelrol speelt, kan deze ook uit de URL gelaten worden, en in dat geval redirect ik automatisch naar dezelfde site, maar dan mét de slug.
Dan krijg je dus een URL zoals: www.website.nl/nieuws/5/nieuwe-website-geintroduceerd.html
Hierbij kijk verplicht ik de slug overigens niet, en is deze ook niet de sleutel in de URL. Als iemand de slug in de URL aanpast, dan laat ik een redirect uitvoeren naar de juiste slug:
www.website.nl/nieuws/5/nieuwe-website-geintroduceerd-bla-die-bla.html
komt weer uit op:
www.website.nl/nieuws/5/nieuwe-website-geintroduceerd.html
Omdat de slug niet de sleutelrol speelt, kan deze ook uit de URL gelaten worden, en in dat geval redirect ik automatisch naar dezelfde site, maar dan mét de slug.
Ok. Ik moet de slug jan-peter-balkenende dan bij de persoon met ID 1 toevoegen in de database. Maar hoe moet ik dat dan verwerken als ik de ID zelf niet meer wil terugzien in de URL? Dan zou ik de sitestructuur ook moeten wijzigen aangezien de ID dan niet meer in de URL staat, waardoor ik er ook niet meer op kan zoeken? En dan zoeken met de slug?
Ik moet het htaccess nog een beetje onder de knie krijgen, dus probeer het eerst even helder te krijgen hoe en wat.
Ik moet het htaccess nog een beetje onder de knie krijgen, dus probeer het eerst even helder te krijgen hoe en wat.
Ikzelf sla de slug niet apart op, omdat deze toch niet leidend is.
Als je geen ID's in de URL wilt tonen, en dus unieke titels hebt, dan moet je wel de slug opslaan.
Als je geen ID's in de URL wilt tonen, en dus unieke titels hebt, dan moet je wel de slug opslaan.
Het kwartje begint te vallen denk ik hoe het zou moeten. Ik vind zonder ID er net wat cleaner uitzien, maar zoeken op de slug (met index) is weer net wat langzamer neem ik aan? Met een ID in de URL heb je inderdaad geen probleem bij dubbele titels of wijziging (van naam in dit geval) omdat je altijd op ID matcht. Die slug staat er dan meer voor de sier. Dat heeft ook weer zijn voordeel. En dan kan ik de sitestructuur zo laten als ie is toch als ik alleen &slug=jan-peter-balkenende toevoeg.
Ik had wat rondgezocht omdat mijn interesse was gewekt hoe anderen het doen, maar zie dat NOS de id en titel samenvoegt (en daarna split ofzo?) en dat NU.nl zowel een ID als slug gebruikt. Maar bij VI.nl zie ik geen ID's in de URL, die zoeken dus ook op de slug neem ik aan?
Ik had wat rondgezocht omdat mijn interesse was gewekt hoe anderen het doen, maar zie dat NOS de id en titel samenvoegt (en daarna split ofzo?) en dat NU.nl zowel een ID als slug gebruikt. Maar bij VI.nl zie ik geen ID's in de URL, die zoeken dus ook op de slug neem ik aan?
Er zijn verschillende strategieën mogelijk. Bijvoorbeeld eentje waarbij je complete (unieke) URL's opslaat in de database en daar dan de bijbehorende code bijtrekt die op zijn beurt weer de juiste data uit de database trekt. Wat je ook kunt doen is de URL elke keer handmatig on-the-fly ontleden en die dan door dirigeren naar het juiste stuk code om de verdere afhandeling te verzorgen.
Het idee hierbij is (waarschijnlijk) wel altijd de aanwezigheid van één voordeur (single point of entry) in je applicatie. Dit is meestal gewoon index.php. Toegepast op de vorige strategieën vraag je in het eerste geval in index.php de informatie (bijna) rechtstreeks op, en in het tweede geval delegeer je code vanuit index.php verder naar een andere lap code die het request (de pagina aanroep) verder afhandelt.
Het idee hierbij is (waarschijnlijk) wel altijd de aanwezigheid van één voordeur (single point of entry) in je applicatie. Dit is meestal gewoon index.php. Toegepast op de vorige strategieën vraag je in het eerste geval in index.php de informatie (bijna) rechtstreeks op, en in het tweede geval delegeer je code vanuit index.php verder naar een andere lap code die het request (de pagina aanroep) verder afhandelt.
Ik ben flink aan het stoeien geweest met .htaccess en regex, en heb een en ander getest, maar heb nog een aantal vraagjes.
.htaccess
index.php
Op het moment dat ik 'jaar' leeglaat, dus /jaar/categorie/ doe als //xxxx/ dan verspringt xxxx alsware van categorie naar jaar. Niet dat het heel belangrijk is, maar hoort dat zo? Nu kan ik bijvoorbeeld een handeling uitvoeren als jaar niet voorkomt in de array of empty is. Ik heb ze voorlopig namelijk op optioneel gezet als het goed is, al weet ik niet of ik dat zo laat.
Bij pagination en zoekresultaten kan ik het beste gewoon ?a=1&b=2&filter=3&q=blabla laten achter de rewrite? En voor pagina's die bij Google in de zoekresultaten moeten komen de URL rewriten (de canonical)?
Waar ik alleen niet uitkom is hoe ik dit moet toepassen op mijn website. Ik gebruik gedeeltelijk namelijk Wordpress - vanwege het usersysteem - maar voor het aanroepen van de database gegevens etc staat het eigenlijk los van Wordpress. Dit staat nu bij de .htaccess (heb ik niks aan veranderd):
Ik heb bijvoorbeeld de pagina kalender/index.php?jaar=2019&cat=xxxx die door Wordpress/htaccess wordt herschreven naar kalender/?jaar=2019&cat=xxxx. Maar kan ik die dan weer herschrijven naar kalender/2019/xxxx? Dat krijg ik nog niet voor elkaar hoe dat zou moeten.
.htaccess
Code (php)
1
2
3
2
3
# Rewrite for kalender
RewriteEngine On
RewriteRule ^/?([^/]*)?/?([^/]*)?/ index.php?jaar=$1&cat=$2 [NC,QSA,L]
RewriteEngine On
RewriteRule ^/?([^/]*)?/?([^/]*)?/ index.php?jaar=$1&cat=$2 [NC,QSA,L]
index.php
Code (php)
Op het moment dat ik 'jaar' leeglaat, dus /jaar/categorie/ doe als //xxxx/ dan verspringt xxxx alsware van categorie naar jaar. Niet dat het heel belangrijk is, maar hoort dat zo? Nu kan ik bijvoorbeeld een handeling uitvoeren als jaar niet voorkomt in de array of empty is. Ik heb ze voorlopig namelijk op optioneel gezet als het goed is, al weet ik niet of ik dat zo laat.
Bij pagination en zoekresultaten kan ik het beste gewoon ?a=1&b=2&filter=3&q=blabla laten achter de rewrite? En voor pagina's die bij Google in de zoekresultaten moeten komen de URL rewriten (de canonical)?
Waar ik alleen niet uitkom is hoe ik dit moet toepassen op mijn website. Ik gebruik gedeeltelijk namelijk Wordpress - vanwege het usersysteem - maar voor het aanroepen van de database gegevens etc staat het eigenlijk los van Wordpress. Dit staat nu bij de .htaccess (heb ik niks aan veranderd):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# BEGIN LSCACHE
# END LSCACHE
# BEGIN NON_LSCACHE
# END NON_LSCACHE
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Block WordPress xmlrpc.php requests
<Files xmlrpc.php>
order deny,allow
deny from all
allow from 123.123.123.123
</Files>
# END LSCACHE
# BEGIN NON_LSCACHE
# END NON_LSCACHE
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Block WordPress xmlrpc.php requests
<Files xmlrpc.php>
order deny,allow
deny from all
allow from 123.123.123.123
</Files>
Ik heb bijvoorbeeld de pagina kalender/index.php?jaar=2019&cat=xxxx die door Wordpress/htaccess wordt herschreven naar kalender/?jaar=2019&cat=xxxx. Maar kan ik die dan weer herschrijven naar kalender/2019/xxxx? Dat krijg ik nog niet voor elkaar hoe dat zou moeten.
Het idee van een single point of entry is mede dat je intern het verkeer verder kunt delegeren. Daarom is het verstandig om zo min mogelijk RewriteRules (wat in wezen applicatielogica (of routing logica, net wat je wilt) is) hiervoor te bakken.
Als je een applicatie X hebt die volgens dit principe werkt kun je gewoon het beste alle verzoeken in eerste instantie naar de voordeur van applicatie X sturen. Vervolgens kun je in de applicatie zelf de URL verder ontleden.
Concreet zou ik dus alles van de vorm /kalender/* doorsturen naar /kalender/index.php. Dit is de enige RewriteRule die je nodig hebt. In /kalender/index.php kun je verder precies programmeren wat er dient te gebeuren. Dit beslis je op grond van de inhoud van de oorspronkelijk aangeroepen URL, die te vinden is onder $_SERVER['REQUEST_URI'].
Als je een applicatie X hebt die volgens dit principe werkt kun je gewoon het beste alle verzoeken in eerste instantie naar de voordeur van applicatie X sturen. Vervolgens kun je in de applicatie zelf de URL verder ontleden.
Concreet zou ik dus alles van de vorm /kalender/* doorsturen naar /kalender/index.php. Dit is de enige RewriteRule die je nodig hebt. In /kalender/index.php kun je verder precies programmeren wat er dient te gebeuren. Dit beslis je op grond van de inhoud van de oorspronkelijk aangeroepen URL, die te vinden is onder $_SERVER['REQUEST_URI'].
Jullie zijn behoorlijk wat gevorderder dan ik dus moet het nauwkeurig lezen om het goed te kunnen volgen. Maar voor alle pagina's en ook de kalender heb ik alleen een index.php. Die werd al rewritten door Wordpress/htaccess tot kalender/?jaar=2019&cat=xxxx. Dan heb ik een 'single point of entry' neem ik aan? Van daaruit wordt afhankelijk van de input bepaald wat er moet gebeuren.
Maar dat wil ik dus SEO-vriendelijk maken. Hoe zou ik die in het laatste voorbeeld moeten herschrijven dan?
Maar dat wil ik dus SEO-vriendelijk maken. Hoe zou ik die in het laatste voorbeeld moeten herschrijven dan?
Een 'single-point-of-entry' kan je vergelijken met de voordeur van een huis. Alles wat naar binnen komt gaat via de voordeur, dus via de index.php. In je .htaccess geef je aan of fysieke directory's en bestanden voorrang krijgen, maar naast dat gaat alles via index.php. Daarvandaan moet je een routeer-script plaatsen die de $_SERVER['REQUEST_URI'] uitleest, en vervolgens het juiste script ophaalt via een include bijvoorbeeld.
Oké, kan dat ook met $_GET of alleen met $_SERVER['REQUEST_URI']?
Maar hoe moet ik dat concreet vormgeven in die onderste .htaccess. Dat krijg ik met geen mogelijkheid werkend.
Maar hoe moet ik dat concreet vormgeven in die onderste .htaccess. Dat krijg ik met geen mogelijkheid werkend.
$_GET is voor uitlezen van query-strings in de URL, zoals: www.site.nl?pagina=blah&jaar=2019
Dat heb je niet nodig als je met een URL als site.nl/blah/2019 zou werken. Dan bouw je die segmenten (blah, 2019 etc..) op aan de hand van $_SERVER['REQUEST_URI'].
Mijn .htaccess ziet er in hoofdlijnen zo uit:
Dat heb je niet nodig als je met een URL als site.nl/blah/2019 zou werken. Dan bouw je die segmenten (blah, 2019 etc..) op aan de hand van $_SERVER['REQUEST_URI'].
Mijn .htaccess ziet er in hoofdlijnen zo uit:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Zet RewriteEngine aan
RewriteEngine on
# Werk vanuit de webroot, gebruik dan een /
RewriteBase /
# Stuur elke request door naar index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA]
RewriteEngine on
# Werk vanuit de webroot, gebruik dan een /
RewriteBase /
# Stuur elke request door naar index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA]
Gewijzigd op 08/03/2019 16:08:33 door - Ariën -
Zoals ik al zei, stuur alles van de vorm /kalender/* door naar /kalender/index.php
Maak vervolgens een index.php onder kalender met de volgende simpele inhoud:
Vervolgens kun je jouw kalender-directory aanroepen zoals je wilt:
http://www.domein.nl/kalender/het/maakt/niet/uit/wat/hierachter/komt
Dit komt allemaal bij jouw /kalender/index.php terecht, het pad begon immers met /kalender.
Jouw /kalender/index.php bepaalt wat er vervolgens met zo'n URL gebeurt:
#1 is dit een bestaande "pagina": toon de bijbehorende functionaliteit
#2 is dit een niet-bestaande "pagina": toon een 404-pagina
#1 en #2 programmeer je beide in /kalender/index.php, op grond van de inhoud van de aangeroepen URL (op te vragen via $_SERVER['REQUEST_URI']).
Maak vervolgens een index.php onder kalender met de volgende simpele inhoud:
Vervolgens kun je jouw kalender-directory aanroepen zoals je wilt:
http://www.domein.nl/kalender/het/maakt/niet/uit/wat/hierachter/komt
Dit komt allemaal bij jouw /kalender/index.php terecht, het pad begon immers met /kalender.
Jouw /kalender/index.php bepaalt wat er vervolgens met zo'n URL gebeurt:
#1 is dit een bestaande "pagina": toon de bijbehorende functionaliteit
#2 is dit een niet-bestaande "pagina": toon een 404-pagina
#1 en #2 programmeer je beide in /kalender/index.php, op grond van de inhoud van de aangeroepen URL (op te vragen via $_SERVER['REQUEST_URI']).
@Thomas: Ik had op zijn minst wel verwacht dat je jouw artikel hier zou aanhalen :-P
http://fangorn.thijma.nl/news/redirecting-all-requests-to-index-php-with-htaccess
http://fangorn.thijma.nl/news/redirecting-all-requests-to-index-php-with-htaccess
Dat had ik ook wel gedaan, ware het niet dat de topicstarter aangaf dat deze kalenderfunctionaliteit naast een Wordpress installatie bestaat, het is dus niet de bedoeling dat *alles* wordt geredirect, enkel alles van de vorm /kalender :).
EDIT: maar ja, daar staat wel uitgelegd hoe je hier makkelijk het pad uitvist, wat je verder kunt helpen om te bepalen wat er dient te gebeuren.
EDIT: maar ja, daar staat wel uitgelegd hoe je hier makkelijk het pad uitvist, wat je verder kunt helpen om te bepalen wat er dient te gebeuren.
Gewijzigd op 08/03/2019 16:29:55 door Thomas van den Heuvel
Oké, onderstaande werkt in een normale setting. Maar hoe kan ik dit combineren met Wordpress. Daar krijg ik het niet voor elkaar. Als ik dat toevoeg aan de bestaande .htaccess daar levert dat niks op. Dan krijg ik gewoon de 404 pagina.
Het bestand kalender.php staat in de WP-content map als thema en die wordt vervolgens gebruikt als pagina template met /kalender als permalink. En is dus de pagina website.com/kalender/index.php.
Het bestand kalender.php staat in de WP-content map als thema en die wordt vervolgens gebruikt als pagina template met /kalender als permalink. En is dus de pagina website.com/kalender/index.php.
De kalender staat nu dus wel in de Wordpress-directory, maar maakt niet gebruik van de core-functies van Wordpress zelf? Dan zou ik eerder denken dat je er beter een Wordpress add-on van kan maken. Dan maak je meteen gebruik van alle basisfuncties, zoals deze: https://codex.wordpress.org/Function_Reference/get_query_var
Ik denk dat je het nu juist lastiger maakt doordat twee verschillende site in een enkele probeert te bouwen met beiden een aparte basis.
Ik denk dat je het nu juist lastiger maakt doordat twee verschillende site in een enkele probeert te bouwen met beiden een aparte basis.
Gewijzigd op 08/03/2019 18:57:26 door - Ariën -
De structuur van de pagina (en alle andere) is:
Ik hoop wel met een volledige PHP-tag.
Maar gebruik je dus aparte scripts buiten Wordpress zelf om in de Wordpress directory? Ook als je dingen uit de database ophaalt, behoor je dit niet in een template te doen, maar juist via een functie, en bij Wordpress is daar een add-on uitstekend voor geschikt.
Maar gebruik je dus aparte scripts buiten Wordpress zelf om in de Wordpress directory? Ook als je dingen uit de database ophaalt, behoor je dit niet in een template te doen, maar juist via een functie, en bij Wordpress is daar een add-on uitstekend voor geschikt.
Gewijzigd op 08/03/2019 19:29:03 door - Ariën -
Haha, ja foutje.
Ik gebruik inderdaad eigen scripts daar tussen in. Het is vooral een databasewebsite waarbij ik dmv $_GET de parameters ophaal en die verwerk. Ik gebruik wel enkele plugins als een User plugin, Cookie en SSL bv. Maar ben daar niet echt fan van zolang het buiten Wordpress om kan.
Ik gebruik inderdaad eigen scripts daar tussen in. Het is vooral een databasewebsite waarbij ik dmv $_GET de parameters ophaal en die verwerk. Ik gebruik wel enkele plugins als een User plugin, Cookie en SSL bv. Maar ben daar niet echt fan van zolang het buiten Wordpress om kan.
Wat dacht je van dezelfde database-connectie gebruiken en de functies die Wordpress allemaal al biedt, zoals de genoemde URL-functie? Ik vind het verre van logisch om een site in een site te bouwen :-P
Wat houdt je tegen om een add-on te schrijven?
Wat houdt je tegen om een add-on te schrijven?




