Posted in: PHP

Create CMS Using PHP with SEO Friendly URLs


Hello friends today’s tutorial is all about Create CMS Using PHP.  CMS stands for Content Management System. CMS is very useful for creating Blog or Website. Basically CMS is used for managing content dynamically. CMS is used widely and many CMS are already there in the market like WordPress, Drupal, Joomla etc they are big and having many features which we dont want in our application or website. So we create our CMS according to our need. In this tutorial we will create the CMS using PHP with SEO Friendly URLs.

In this tutorial We will create front end and admin end so we will start with the Admin end first.

Admin Panel

  1. Dashboard (dashboard.php)
  2. Add Page (add-page.php)
  3. Edit Page (edit-page.php)
  4. Manage Page (manage-page.php)
  5. Login Page (index.php)

Admin Panel Directory Structure

  1. admin
    • functions (Directory)
      • connectionClass.php
      • gump.class.php
    • inc (Directory)
      • header
    • login (Directory)
      • loginClass.php
    • messages (Directory)
      • alertClass.php
    • pages (Directory)
      • pageClass.php
    • add-pages.php
    • dashboard.php
    • edit-pages.php
    • index.php
    • logout.php
    • manage-pages.php

 

Front End

  1. Index Page (index.php)

Lets start with Step by Step.  First we will start with creating the login script with login page.

Login Page (index.php)



<?php 
error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
include_once 'messages/alertClass.php';
$message=new alertClass();
if(isset($_POST["login"])){
    $username=$_POST["Username"];
    $password=$_POST["Password"];
    
    if($username==""||$password==""){
        $alert=$message->getAlert("Please enter both the values", "error");
    }
    else
    {
        define('pageclassconst', TRUE);
        include_once 'login/loginClass.php';
        $logincheck=new loginClass();
        $alert=$logincheck->checkLogin($username,$password);
    }
}
?>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Application Panel</title>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <link rel="stylesheet" href="../css/bootstrap.min.css" type="text/css">
    <link rel="stylesheet" href="../css/signin.css" type="text/css">
  </head>
<body>

    <div class="container">
        <?php echo $alert; ?>
        <form class="form-signin" method="post" action="<?php echo $_SERVER["PHP_SELF"] ?>">
        <h2 class="form-signin-heading">Please sign in</h2>
        <label for="inputEmail" class="sr-only">Username</label>
        <input type="text" id="Username" name="Username" class="form-control" placeholder="Username" required autofocus>
        <label for="inputPassword" class="sr-only">Password</label>
        <input type="password" id="Password" name="Password" class="form-control" placeholder="Password" required>
        <button class="btn btn-lg btn-primary btn-block" type="submit" name="login">Sign in</button>
      </form>

    </div> <!-- /container -->

  </body>
</html>

Above code will create a login window. We use the username and password for login. After clicking submit we will go for checking the submitted values.

Username – admin

Password – demo

loginClass.php – We will use this class for check login and save the session values for maintaining the login.

public function checkLogin($username,$password){
        $username= $this->real_escape_string($username);
        $password=  $this->real_escape_string($password);
        $pass = urlencode($password);
        $messages=new alertClass();
        if($username==""||$password==""){
            return $messages->getAlert("Values are empty", "warning");
        }
        else{
            $query="select * from members where username='$username'";
            $result=  $this->query($query);
            $count=  $result->num_rows;
            if($count < 1){
                return $messages->getAlert("Access Denied", "error");
            }
            else{
                $row=  $result->fetch_array(3);
                if($row["password"]==crypt($pass, $row["password"])){
                $_SESSION["username"]=$row["username"];
                $_SESSION["password"]=$row["password"];
                if($_SESSION["username"]==""||$_SESSION["password"]==""){
                    return $messages->getAlert("Some error occurred", "error");
                }
                else
                {
                    header("Location:dashboard.php");
                }
                }
                else
                {
                    return $messages->getAlert("Access Denied", "error");
                }
            }
        }
    }

In the above code first we will sanitize the values using the mysqli_real_escape_string function.  After getting the values we will first check the Username if we will find it than we will move for checking the password. If everything goes perfect than we will save the values to session and redirect the page to the Dashboard.php.

Dashboard (dashboard.php)

This page is just a welcome page and for showing the counting of how many pages you have added. This page will come when you successfully login.

<?php include_once './inc/header.php';
error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
include_once 'pages/pageClass.php';
$pageClass=new pagesClass();
?>
 <div class="container-fluid">
 <div class="row">
 <div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 main">
 <h1 class="page-header">Dashboard</h1>
 <div class="panel panel-default">
 <!-- Default panel contents -->
 <div class="panel-heading">Total Pages Added</div>
 <div class="panel-body">
 <h1><?php echo count($pageClass->listPages()); ?></h1>
 </div>
</div>
 
 </div>
 </div>
 </div>

 <!-- Bootstrap core JavaScript
 ================================================== -->
 <!-- Placed at the end of the document so the pages load faster -->
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
 <script src="../js/bootstrap.min.js"></script>>
 </body>
</html>

 Add Page (add-page.php)

We will use this page to add new pages to our website. In this we have use some text boxes so that it will helpful for us to enter the data to the database.

<?php include_once './inc/header.php';
include_once 'messages/alertClass.php';
$message=new alertClass();
if(isset($_POST["submit"])){
    include_once 'functions/gump.class.php';
    $gump = new GUMP();
    $gump->validation_rules(array(
    'Title'    => 'required',
        'URL'    => 'required',
        'PageDetails'    => 'required',
        'PageName'    => 'required'
));
    $gump->filter_rules(array(
    'Title'    => 'trim|sanitize_string',
        'URL'    => 'trim|sanitize_string',
        'Keywords'    => 'trim|sanitize_string',
        'Description'    => 'trim|sanitize_string',
        'PageName'    => 'trim|sanitize_string'
));
    $validated_data = $gump->run($_POST);
    if($validated_data === false) {
    $alert=$message->getAlert($gump->get_readable_errors(true),"error");
} else {
        unset($validated_data['submit']);
        define('pageclassconst', TRUE);
        include 'pages/pageClass.php';
        $pageClass=new pagesClass();
        $alert=$pageClass->addPage($validated_data);
}
}
?>

    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-8 col-md-offset-2 main">
          <h1 class="page-header">Add Pages</h1>
          <?php echo $alert; ?>
          <form method="post" action="<?php echo $_SERVER["PHP_SELF"] ?>" enctype="multipart/form-data">
              <div class="form-group">
                  <label>Page Name*</label>
                  <input type="text" id="PageName" name="PageName" value="<?php echo $_POST["PageName"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>Title*</label>
                  <input type="text" id="Title" name="Title" value="<?php echo $_POST["Title"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>URL*</label>
                  <input type="text" id="URL" name="URL" value="<?php echo $_POST["URL"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>Meta Keywords</label>
                  <input type="text" id="Keywords" name="Keywords" value="<?php echo $_POST["Keywords"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>Meta Description</label>
                  <textarea id="Description" name="Description" class="form-control"><?php echo $_POST["Description"] ?></textarea>
              </div>
              <div class="form-group">
                  <label>Page Details*</label>
                  <textarea id="summernote" name="PageDetails"><?php echo $_POST["PageDetails"] ?></textarea>
              </div>
              <input type="submit" id="submit" name="submit" value="Add Page" class="btn btn-primary">
          </form>
        </div>
      </div>
    </div>

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="../js/bootstrap.min.js"></script>
    <script src="../js/summernote/summernote.min.js"></script>
    <script>
    $(document).ready(function() {
        $('#summernote').summernote({
  height: 300,                 // set editor height
  minHeight: null,             // set minimum height of editor
  maxHeight: null,             // set maximum height of editor
  focus: true                  // set focus to editable area after initializing summernote
});
    });
  </script>
  </body>
</html>

We have used the summernote as editor for adding the page details.

We have used the gump class so that we will validate the form before submitting the form.

Manage Page (manage-page.php)

This page will list all the added pages for edit and delete. This page will show the data in table format.



<?php include_once './inc/header.php';
define('pageclassconst', TRUE);
include_once 'pages/pageClass.php';
$pageClass=new pagesClass();
include_once 'messages/alertClass.php';
$message=new alertClass();
if(isset($_POST["delete"])){
    $deleteid=$_POST["did"];
    if($deleteid==""){
        
    }
    else
    {
        
        $alert.="<form method=post>";
        $alert.= $message->getAlert("Are you sure you want to delete 
            <input type='hidden' name=cdid value='$deleteid'>
            <input type='submit' name='cdel' class='btn btn-sm btn-danger' value='Yes'> &nbsp; 
            <input type='submit' name='ndel' class='btn btn-sm btn-primary' value='No'>", "warning");
        $alert.= "</form>";
    }
}

if(isset($_POST["cdel"])){
    $confirmId=$_POST["cdid"];
    if(!$confirmId==""){
        $alert=$pageClass->deletePage($confirmId);
    }
}
$pageList=$pageClass->listPages();
?>

    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 main">
          <h1 class="page-header">Pages List</h1>
          <?php echo $alert; ?>
          <div class="table-responsive">
            <table class="table table-striped">
              <thead>
                <tr>
                  <th>#</th>
                  <th>Name</th>
                  <th>Title</th>
                  <th>URL</th>
                  <th>Action</th>
                </tr>
              </thead>
              <tbody>
                  <?php
                  $i=1;
                    if(count($pageList)){
                        foreach ($pageList as $value) {
                            echo "<tr>
                                <td>$i</td>
                                <td>$value[PageName]</td>
                                <td>$value[Title]</td>
                                <td>$value[URL]</td>
                                <td><a class='btn btn-warning btn-sm' href='edit-pages.php?eid=$value[id]'>Edit</a>&nbsp;&nbsp;&nbsp;
                  <form action='$_SERVER[PHP_SELF]' method=post>
<input type=hidden value='$value[id]' name='did' id='did'>                      
<input type=submit name=delete value=Delete class='btn btn-danger btn-sm'></form></td>
                                </tr>";
                            $i++;
                        }
                    }
                  ?>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="../js/bootstrap.min.js"></script>
  </body>
</html>

Edit Page (edit-page.php)

Edit page will work same as add page it will just take the values from Get global variable and show the values in the text boxes. When you click on the update it will update the current data.

<?php include_once './inc/header.php';
include_once 'messages/alertClass.php';
$message=new alertClass();
define('pageclassconst', TRUE);
include 'pages/pageClass.php';
$pageClass=new pagesClass();
if(isset($_POST["submit"])){
    include_once 'functions/gump.class.php';
    $gump = new GUMP();
    $gump->validation_rules(array(
    'Title'    => 'required',
        'URL'    => 'required',
        'PageDetails'    => 'required'
));
    $gump->filter_rules(array(
    'Title'    => 'trim|sanitize_string',
        'URL'    => 'trim|sanitize_string',
        'Keywords'    => 'trim|sanitize_string',
        'Description'    => 'trim|sanitize_string'
));
    $validated_data = $gump->run($_POST);
    if($validated_data === false) {
    $alert=$message->getAlert($gump->get_readable_errors(true),"error");
} else {
        unset($validated_data['submit']);
        $alert=$pageClass->updatePage($validated_data,$_GET["eid"]);
}
}
$id=$_GET["eid"];
$pageDetails=$pageClass->particularPage($id);
?>
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-8 col-md-offset-2 main">
          <h1 class="page-header">Update Pages</h1>
          <?php echo $alert; ?>
          <form method="post" action="<?php echo $_SERVER["PHP_SELF"]."?eid=$id" ?>" enctype="multipart/form-data">
              <div class="form-group">
                  <label>Page Name*</label>
                  <input type="text" id="PageName" name="PageName" value="<?php echo $pageDetails["PageName"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>Title*</label>
                  <input type="text" id="Title" name="Title" value="<?php echo $pageDetails["Title"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>URL*</label>
                  <input type="text" id="URL" name="URL" value="<?php echo $pageDetails["URL"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>Meta Keywords</label>
                  <input type="text" id="Keywords" name="Keywords" value="<?php echo $pageDetails["Keywords"] ?>" class="form-control">
              </div>
              <div class="form-group">
                  <label>Meta Description</label>
                  <textarea id="Description" name="Description"  class="form-control"><?php echo $pageDetails["Description"] ?></textarea>
              </div>
              <div class="form-group">
                  <label>Page Details*</label>
                  <textarea id="summernote" name="PageDetails"><?php echo $pageDetails["PageDetails"] ?></textarea>
              </div>
              <input type="submit" id="submit" name="submit" value="Update Page" class="btn btn-primary">
          </form>
        </div>
      </div>
    </div>

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="../js/bootstrap.min.js"></script>
    <script src="../js/summernote/summernote.min.js"></script>
    <script>
    $(document).ready(function() {
        $('#summernote').summernote({
  height: 300,                 // set editor height
  minHeight: null,             // set minimum height of editor
  maxHeight: null,             // set maximum height of editor
  focus: true                  // set focus to editable area after initializing summernote
});
    });
  </script>
  </body>
</html>

Delete Page

Deletion of page is available at the manage-page.php. In the Action column you will find a link named Delete. When you press the button you will see a warning for confirmation if you press “Yes” It will delete the page.

 

Front End

As you can see We have created the Login page, Add page, Edit page, Manage Page, Delete Page functions. Now we will move to our Website Front end. Its so simple and easy. You have to just show the data from the Database using the Page Class.

We will call all the pages over the index.php and show the details according to the pages clicked. Here we can call the data by using 2 types. 1 Calling by Id 2. Calling by URL.

Calling by id will work if we use the page links as Id in our navigation like-

<a href="index.php?pid=1">Home</a>

But this is not the approach we are using. We are working over the SEO Friendly URLs and this is not the Seo friendly at all. So we will change the ID to the URL and remove the index.php from the URL. Our Navigation will look like this than.

<a href="home">Home</a>

For doing this we will create a .htaccess file with some lines of code

.htaccess

RewriteEngine On
RewriteBase /cms/

RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ index.php?pid=$1 [QSA,L]
	

First be sure that rewrite is enable in your server otherwise it will not work. We have used the RewriteBase as /cms/ you can use anything here you want but it should be the name of your Folder like i am having –  http://tutorials.vivekmoyal.in/cms/what-is-lorem-ipsum

If you dont have any folder than you can remove it also. Now here is our website index.php page for showing all the information.

index.php

<?php
error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
define('pageclassconst', TRUE);
include_once 'admin/pages/pageClass.php';
$pageClass=new pagesClass();
$pageList=$pageClass->listPages();
$pid=$_GET[pid];
if($pid==""){
    $pageDetails=$pageClass->particularPageSlug($pageList[0]['URL']);
}
else
{
    $pageDetails=$pageClass->particularPageSlug($pid);
    if($pageDetails[id]==""){
        header("location:404.php");
    }
}
?>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="<?php echo $pageDetails["Description"] ?>">
    <meta name="keyword" content="<?php echo $pageDetails["Keywords"] ?>">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">
    <title><?php echo $pageDetails["Title"] ?> - vivekmoyal.in</title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link href="css/blog.css" rel="stylesheet">
  </head>

  <body>

    <div class="blog-masthead">
      <div class="container">
        <nav class="blog-nav">
            <?php
                  $i=1;
                    if(count($pageList)){
                        foreach ($pageList as $value) {
                            echo '<a class="blog-nav-item" href="'.$value[URL].'">'.$value[PageName].'</a>';
                        }
                    }
            ?>
            <a class="blog-nav-item" style="color:red" href="http://www.vivekmoyal.in/create-cms-using-php-with-seo-friendly-urls/">View Tutorial</a>
        </nav>
      </div>
    </div>

    <div class="container">

      <div class="blog-header">
        <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Responsive -->
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-5464970129034050"
     data-ad-slot="5130515927"
     data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
      </div>

      <div class="row">
          
        <div class="col-sm-12 blog-main">

          <div class="blog-post">
            <h2 class="blog-post-title"><?php echo $pageDetails["Title"] ?></h2>
            <hr>
            <?php echo $pageDetails["PageDetails"] ?>
          </div>
        </div>

      </div>

    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
  </body>
</html>

We are using a function  – particularPageSlug($pageList[0][‘URL’]). This function will take the data from the database based on the url parameter value. You must be missing some files here so you can download it form our my Github repository.

Download From Here

Demo

 

Comments (19) on "Create CMS Using PHP with SEO Friendly URLs"

  1. Nice project but I need something different – This is not SEO friendly.

    I need:-
    Like-
    I have three categories on my blog – HTML,CSS ,JS
    I write the article –
    So the URL should be like –

    for PHP –
    localhost/php/what-is-php

    for CSS

    localhost/css/where-i-can-learn-css

    for JS articles URL
    like –

    localhost/js/where-i-can-learn-js

    I need this type for SEO friendly URL –

    localhost/category_name/title_slug

    Please help me and change it –

    share the best solution for that. It will be best for SEO.

  2. i am download code and use on local at xammp following error occur
    Warning: Use of undefined constant pid – assumed ‘pid’ (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\cms\index.php on line 7

    what is solution for local …

  3. Hello, is it possible to change the connection for include my db settings
    my db connection File db.php looks so :

    ob_start();
    $db['db_host'] = "localhost";
    $db['db_user'] = "xxx";
    $db['db_pass'] = "xxx";
    $db['db_name'] = "xxx";
    
    foreach($db as $key => $value){
        define(strtoupper($key),$value);
    }
    
    $connection = mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
    
  4. Error found:
    Notice: Undefined index: pid in C:\xampp\htdocs\com\php-cms-master\cms\index.php on line 13
    Menu was showing page not found error after clicking it.
    Resolve as soon as possible I will be highly greatfull to you.

    1. Check your htaccess file. If you are using on local than you will face this issue. Over the server check the htaccess file it will surely work for you

      1. On server getting error : The requested URL /why-do-we-use-it was not found on this server.

              1. You don’t have to use comma”,” before the extension you have to use dot before the htaccess as this is the file extension not the name of the file.

  5. Hi,
    congratulations !

    i downloaded the code but i didn’t find de database structure,
    can you send it to me, please ?

    many thanks.

    1. Warning: Use of undefined constant pid – assumed ‘pid’ (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\cms\index.php on line 7

      how to fix

      1. This is warning regarding the pid variable. It is due to declaration you can update it by proper declaration

        .Sometime when we use the variable and it is not properly declared then it shows this error.

Leave a Reply

Your email address will not be published. Required fields are marked *