Project 1 - Basic CMS for this website

I'm about to embark upon a big project of creating my own CMS based system.

So it's time to get out the pen and paper, but what better time to document such a beast as while you are actually doing it. And what better pen and paper than your very own website. (Plus this gives me time to think on the more finer details)

So this is a blow by blow description of the creating (remember I'm doing this on the fly) of my Looking Over My Shoulder CMS Script or Loms for lazy typists (like me).


Features

Before we can begin any coding, we had best work out what it is we need.

The Wish List (no details)

General page layouts

BreadCrumbs

This will entail a system that knows where we have come from. Technically, everything stems from Home. An example would be Home->HTML->Lesson 1 - these would need to be a field for each page [bc_name]

On Page Prev - Next Links

<Prev Home Next> Links top and bottom. These would require a Prev and Next field - probably settable in the admin area to link pages. Also it would be part of the Navigation system.

A quick example of my templating for CI

If you are totally unfamiliar with Code Igniter I suggest you go visit the Code Igniter website.

Templating

Just a very quick over view of how a framework like Code Igniter works.

Most Frameworks are based on the concept of M V C

So this structure pretty well simulates the way I was coding other websites BUT I never had all the nice pre-written stuff that you get with something like CodeIgniter. So you get the Sturcture and all the basic code you just never have to write again and that's something I like.

So seeing that our website is made up of - templates - let's see how we can setup Code Igniter

Views

This is the template of the main page which is saved under
/public_html/system/application/views/template.php

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/xhtml1-strict.dtd">
<html>
<head>
<meta name="description" content="Looking Over My Shoulder." />
<meta name="keywords" content="Learning PHP,Marketing Tips,Tricks,online conference,forum,php programming,css,html,shoulder" />
<title><?=$title?></title>
<?php foreach ($css_link as $link): ?>
<link rel="stylesheet" type="text/css" href="<?=$link?>" />
<?php endforeach; ?>
</head>
<body>
<p class="note1">When you are learning, it helps to be able to look over someone's shoulder!</p>
<div>
<div class="top_logo">
<p class="rtnav"><a href="/users/login">Login</a> | <a href="/users/register">Register</a></p>
<a href="<?=$home_url?>"><img src="/images/logo.jpg" title="Looking Over My Shoulder Logo" alt="Looking Over My Shoulder Logo" /></a>
</div>
<div class="spacer"></div><!-- end of spacer -->
</div>
<div class="main">
<div class="spacer"></div><!-- end of spacer -->
<div class="sec_left">
<?=$content_left?>
</div><!-- end sec_left -->
<div class="sec_center">
<div class="my_img_left"><img src="<?=$image_path?>Tim_Brownlaw.jpg" title="Tim Brownlaw" alt="Tim Brownlaw" />
</div>
<?=$content?>
</div><!-- end sec_center -->
<div class="spacer"></div><!-- end of spacer -->
<div class="footer">
<hr />
<?=$footer?>
</div><!-- end of footer -->
</div><!-- end of main -->
</body>
</html>

Now you can see we have quite a few statements like <?=$content?>

Normally you would have <?php echo$content ;?>

We get to loose the echo statement and the trailing semicolon ; much nicer

Now to display this View of our template with Code Igniter we will use the instruction

$this->load->view('template' ,$data);

The variable $data is an array of all the variables in the template.

So we have to give values to
$data['description']
$data['keywords']
$data['title']
$data['home_url']
$data['content']
$data['content_left']
$data['image_path']
$data['footer']

And not forgetting $data['css_link'] which is an array of css files.

So if there is one or two or 4 CSS files to be used in our page (which is dependant upon the content), we can. The View Logic will produce the links for us via the foreach loop.

Now I do two things to assign these values. Firstly I have a default that I've currently saved into a Model as it is convenient PLUS it will end up in a database (eventually).

The second thing is a function in each controller where I can override those settings to suit.

This is the model of the main template variables which is saved under
/public_html/system/application/models/page_model.php

<?php
class Page_model extends Model 
{
	function Page_model ()
	{
		parent::Model();
	} 
	function get_config()
	{
		$data['site_url'] =$this->config->item('base_url');
		$data['home_url'] =$data['site_url']."/";
		$data['description'] = "Looking Over My Shoulder";
		$data['keywords'] = "HTML.HTML Tutorial,PHP Tutorial,CSS Tutorial,Mysql Tutorial,Codeigniter Tutorial";
		$data['css_link'] = array(
				base_url().'css/layout.css',
				base_url().'css/main.css'
				);
		$data['image_path'] = base_url().'images/';
		$data['content_left'] = "";
		$data['footer'] =<<<fred
<p>Page rendered in 0.0519 seconds</p>
fred;
		return $data;
	}
}
?>

So I can change anything in this model and it will effect all pages that use it ( they all should ) with the advantage of being able to change these down at the page level if I want to.

Note: If you do not define the variables used in a View, Code Igniter will tell you so via a warning message - which is very neat.

You can consider this page_model.php file as an include file of a kind. Except that it returns the values from a function. All in keeping with the CI Structure. But there is no reason that you couldn't use an include file. CI will let you do what you like. Which is another very neat aspect of CI.

This is the controller which calls the Model and the View
/public_html/system/application/controller/home.php

<?php

class Home extends Controller {
	function Home()
	{
		parent::Controller();	
		$this->load->helper('url');
		$this->load->config('myconfig');
// This is our default page information to share between the controllers
		$this->load->model('page_model','cpage');
		$this->load->model('menu_model','nav');
	}

// This is our local page information to share between the controller methods
	function _get_local_page()
	{
		$data['title'] = "";
		return $data;
	}
	function index()
	{
		$data = $this->cpage->get_config();
		$data = array_merge($this->_get_local_page(),$data);
		$page = $this->load->view('homepage_view','',True);
		$page_name = "home";
		$data['content_left']=$this->nav->left_nav($page_name);
		$data['content'] = $page;
		$data['title'] = $this->config->item('site_name')." Home";
		$this->load->view('template',$data);
	}
}
?>

You'll notice a few things called in the Home Constructor.

There is a call to load the config file "myconfig". It just has a few settings for the application. and there are two calls to models.

One is to page_model as described above and the other is the menu_model where I build the menu

You'll see in the function index() thatit calls the page_model (renamed to cpage) function get_config(). This gives us our global default settings.

Then straight after that we call the local internal function function _get_local_page() and we merge the two arrays.

Merging will replace any existing entries with the new ones effectively allowing us to override the global default settings from the page_model model.

Then we can again override those for each function in the controller, typcially the $data['title'] and $data['content'] and what ever else you are using in your templates

It's not pretty but it works

I'm sure there are other ways to achieve this but this is how it stands at the moment until I discover a better method.

Maybe this has given you some inspiration into doing it better!