This tutorial will explain how to change the simple CMS to use search engine friendly urls instead of the query strings.
This will be editing the existing system built in Building a content management system from scratch as a result only new modifications will be shown and not the full code base.
Demo: https://demos.dcblog.dev/simple-cms-seo
admin demo: admin
username: admin
password: admin
In order to use search engine friendly urls a .htaccess file is needed create a new file in the root of the project called .htaccess then add:
RewriteEngine On
RewriteBase /simple-cms/
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ index.php?p=$1 [QSA,L]
Change the RewriteBase to match the path of your site up this should the be the relative path from the root of the domain.
The next two lines are to ignore requests for files and directories the last line passes all requests to index.php passing them as query strings in ?p=
This will allow urls like
domain.com?p=3 to become domain.com/my-nice-page
The ?p can still be used inside the project but the system will be updated to use the SEO url version.
Update the database and edit the table pages table and add a new column called pageSlug type will be varchar set to 255 in length
Next open includes/functions.php and add this new function:
function slug($text){
// replace non letter or digits by -
$text = preg_replace('~[^pLd]+~u', '-', $text);
// trim
$text = trim($text, '-');
// transliterate
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
// lowercase
$text = strtolower($text);
// remove unwanted characters
$text = preg_replace('~[^-w]+~', '', $text);
if (empty($text))
{
return 'n-a';
}
return $text;
}
This will let us generate a slug to be used in the database is takes a string and returns it with spaces replaced with - and symbols removed.
Next open admin/addpage.php replace the if statement on line 10 to this:
if(isset($_POST['submit'])){
$title = $_POST['pageTitle'];
$content = $_POST['pageCont'];
$title = mysql_real_escape_string($title);
$content = mysql_real_escape_string($content);
$pageSlug = slug($title);
mysql_query("INSERT INTO pages (pageTitle,pageSlug,pageCont) VALUES ('$title','$pageSlug','$content')")or die(mysql_error());
$_SESSION['success'] = 'Page Added';
header('Location: '.DIRADMIN);
exit();
}
This will create the slug from the post title '$pageSlug = slug($title);' then add that into the database.
Do the same for admin/editpage.php on line 15.
if(isset($_POST['submit'])){
$title = $_POST['pageTitle'];
$content = $_POST['pageCont'];
$pageID = $_POST['pageID'];
$title = mysql_real_escape_string($title);
$content = mysql_real_escape_string($content);
$pageSlug = slug($title);
mysql_query("UPDATE pages SET pageTitle='$title', pageSlug='$pageSlug', pageCont='$content' WHERE pageID='$pageID'");
$_SESSION['success'] = 'Page Updated';
header('Location: '.DIRADMIN);
exit();
}
Now pages that are added or edited will use save the pageSlug in the database, all that is left is to update index.php
on index.php find:
if($row->pageID == $_GET['p']){ $sel="id='current'";} else { $sel='';}
echo "<li><a href="".DIR."?p=$row->pageID" $sel>$row->pageTitle</a></li>";
replace with:
if($row->pageSlug == $_GET['p']){ $sel="id='current'";} else { $sel='';}
echo "<li><a href="".DIR."$row->pageSlug" $sel>$row->pageTitle</a></li>";
That will use the pageSlug in the urls instead of ?p=
On line 54 find
$q = mysql_query("SELECT * FROM pages WHERE pageID='$id'");
replace with
$q = mysql_query("SELECT * FROM pages WHERE pageSlug='$id'");
That's it now all pages will use the pageSlug instead of the pageID.