Step 5 – Administer static pages for our multilanguage CMS – creating the pages

Created at: March 31, 2015; Last update: February 26, 2017

(created at: April 01, 2015; last update: April 03, 2015)
Let’s try and do a interface for creating and editing static pages in our multilanguage CMS. First of all what is a “static page”? A static page is a page that doesn’t change (a lot) in time, doesn’t have a publication date and is independent of any time span.

First we will create the tables. I am thinking of keeping the pages’ content in two tables. One that will keep the common data related to all translations (like the id of the page, the parent of the page, the order of importance inside the parent of page, the creation date, modified date, deleted date), and the other one will keep the translations of the pages:

Let’s create our Pages.php inside application/controllers/admin directory:

As you can see, we already have loaded the necessary models needed to work with pages, the form validation library and the text helper. I will tell you later why we needed it.

Now let’s do the create() method. This one will receive two parameters: the language slug and page_id. The language slug will allow us to put a hidden input element and also to have the parent pages available. If no language is set, the application will create the page in the default language. The page id, if one is set will tell our application that the form will be used only for a translation and not for creation of a new page.

Let’s see how we use the language slug and page id:

Now, before outputing the form, we need to setup the rules. Considering that we don’t want to repeat ourselves, what if we keep those rules inside the models? Let’s keep in mind that we have rules for inserting data and rules for updating data.

So, for now, let’s put these rules inside the Page_model:

As you can see, this Page_model is extending a MY_Model. The MY_Model I am using is the one I’ve made and is posted on Github: You can simply move that MY_Model.php into application/core.

Returning to our Pages controller, let’s set the rules and ask the application if the form validation ended with success. If it didn’t, we load the form view.

Now, the else part. So, if all went well with our form… Oh… where is the form… Let’s create the form inside application/views/admin/pages/create_view.php

Now, returning to our else block that we started before creating the view… If the form was submitted and the form validation passed, we will retrieve all the data from the input:

It’s in here that I’ve used the text helper. See function ellipsize()…

As you can see, we make sure we use everything we have, even if the user is not filling all the input fields. Also, you can at any time insert a <!–more–> comment inside the content and the application will take the string until it meets that html comment and make the teaser (just like WordPress).

Now what do we do with all this data. First we make sure we have a page id. If the page id is 0, that means we need to create a new row inside the pages table.

After we’ve retrieved the page id, we create the translation and the slug:

Let’s explain what we did here. First of all we filled the created_by column with a variable that doesn’t exist $this->user_id. Let’s create that variable inside our Admin_Controller, taking it from the users table:

Now… you also may have noticed that we used some sort of new method named _verify_slug() which received the slug and the language slug as parameters. This private method that we will define in the current controller will verify if the slug is already defined in a “slugs” table. If it exists it will append to the slug an incremental value until it finds a slug that doesn’t exist:

But what about the “slugs” table? Let’s create it:

Once we’ve created the “slugs” table we also have to create a Slug_model. So let’s create a file named Slug_model.php inside application/models directory:

And that’s it for the creation of pages.

Now let’s see the whole controller again:

Next we will see how to create the index() method for the Pages controller.

6 thoughts on “Step 5 – Administer static pages for our multilanguage CMS – creating the pages

  1. Daniel


    here :
    “if($translation_id = $this->page_translation_model->insert($insert_data))
    $url = $this->_verify_slug($slug,$language_slug);

    i don’t see where did you load the slug model? , you use it but you did not loaded,
    it is not a better solution to put the 100 line $this->load->model(‘slug_model’); in the constructor?

    i did not tested yet if is working (your version) if the model is available because you call the function = $this->_verify_slug($slug,$language_slug); and only after you call the insert method of slug_model.

    1. avenirer Post author

      Yes, I guess that is what I did, I’ve put it inside the constructor. It is a much better idea to load the models in the constructor, as they are usually used by more than one controller method.

  2. Jim Pannell

    I’m guessing this method of holding the page hierarchy uses the Adjacency List Model. In your experience how many levels deep can your page hierarchy go using this method?

    1. avenirer Post author


      To be honest is more like an Adjacency List Model combined with 50% of a Nested Set Model (as it doesn’t have a left and a right parameters but an order parameter). This model can go as deep as you want. Combined with the theory I presented in here (, the retrieval of the whole tree would only need one database query and one pass through the whole result set.

  3. robert

    After create_view.php everything becomes blur! you did not mention where we have to load next codes just you said we put this code this code and that code!

    Can you be more specific please?

    1. avenirer Post author

      You are right. Sorry about that. After creating the view, you should return to the “else” block, and add that code I am talking about.


Leave a Reply

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

No spam? * Time limit is exhausted. Please reload CAPTCHA.