• Join Now
  • Sign In
  • Cart
  • Instant Setup
  • Download
Logo
  • About
    • Try it Out
    • Site Editor Tour
    • Designer Tour
    • Developer Tour
    • Testimonials
    • Showcase
    • History
    • Our Philosophy
    • Credits
    • What does free mean?
    • Blog
  • Community
    • Members
    • Forums
    • Chat
    • Karma
    • International
    • Jobs
    • eNewsletters
  • Developers
    • Download concrete5
    • Join Beta Team
    • Translate concrete5
    • Bug Tracker
    • Submit to Marketplace
    • Code Submissions
    • News
    • Community Leaders
  • Marketplace
    • Add-Ons
    • Themes
    • Installation Help
    • Deal Of The Day
    • Swag
  • Services
    • Hosting
    • Support Options
    • Consulting
    • Training
    • Enterprise
  • Documentation
    • Getting Started
    • Editor's Guide
    • Developers Guide
    • How-Tos
    • Basics
  • How-Tos

Basic MVC in concrete5

Posted byandrew in Developers on Aug 16, 2010.
4 people like this.

In concrete5, any page shown to a visitor is either an instance of a page type (this is the most common - typical examples include "Left Sidebar", "About", "Three Column", etc...) or a single page. These are one-off pages that typically contain functionality (e.g. "Dashboard", "Login", "User Profile", etc...). These single pages, and even page type instances, can have controllers attached to them to allow a separation between the presentation layer of the single page or page type template, and the functionality bound to it.

While they have an imposing name, controllers are really just PHP classes with functions that are automatically run at certain times. This makes them ideal for handling form submissions and page rendering. Controllers allow messy business logic and PHP functions to be kept away from the actual presentation layer, which makes code easier to read and more maintanable.

Single Pages do not require controllers, but in most cases, a single page without a controller would be better served by having one.

Setting up a form to require a controller

Let's say we have a search form in our "my_profile.php" example that's lets us enter a user's name, and get information about them back. This is a very simple example, but hopefully it will show the way single pages and controllers can help make web development easier.

    <form method="post" 
    action="<?php echo $this->action('search_user')?>">
    <input type="text" name="uName" value="" /> 
    <input type="submit" value="Search" />
    </form>
 

This is a simple form. But notice the action: by using the View::action() method we're submitting the form back to our current page, and setting the task to be run to search_user. This function will live within the controller, and be automatically run when this page is submitted.

Note: If we wanted to submit the page to a different single page, but still use a task, we could do so by specifying the action as

    <?php echo $this->url('/path/to/second/single/page', 'second_search_user')?>

Finally, View::url() can take a variable number of arguments. The first one is always the view to which the URL will link, the second is always the function that will be run within that controller, but all arguments after that will be passed to that function. For example, let's say I have a single page named "calculator" that I want to at:

http://www.yoursite.com/index.php/calculator/

And I want to run the "multiply" method on calculator, and the multiple method takes two numbers:

   public function multiply($num1, $num2) {
        $this->set('answer', $num1 * $num2);
    }

If I wanted to multiply 5 * 10, I would write

   <a href="<?php echo $this->url('/calculator',  'multiply', 5, 10)?>">Multiply Here!</a>

Creating a Single Page Controller

Controllers are even easier to create than single pages. Simply add the correct PHP class, correctly named, to the controllers/ directory in your web root, and the controller will be available.

  1. Create an empty file named controllers/my_profile.php
  2. Open the file in a text editor, and paste the following information into the file:

Paste:

    <?php
    class MyProfileController extends Controller {
    	public function search_user() {
    		print 'I am running!';
    	}
    }
 

The class must be named correctly, or else it won't be run. You must name your controllers the full name of their directory, plus filename, plus "Controller", and capitalize any instance where a directory occurs or an underscore occurs. That sounds confusing but hopefully gets easier to understand with some examples.

/controllers/my_profile.php = MyProfileController /controllers/dashboard/sitemap.php = DashboardSitemapController /controllers/cart/checkout/my_test.php = CartCheckoutMyTestController

All of these classes must extend the Controller class. Don't worry about loading this class - it's already loaded by the time your controller is called.

Finally, like views, controllers can be nested in directories. If your controller is nested in a directory but needs to refer to the view for that directory, name this file "controller.php."

For example, if you have a single page at

/single_pages/cart/view.php

You'd place your controller at

/controllers/cart/controller.php

and name it

CartController

Passing data from views to controllers, and back again

Notice the search_user function in the controller? This function simply prints out a line of text - and in our example above, whenever you submit the form, this line of text will be printed out at the top of the page, because search_user is automatically running.

Of course, this isn't that useful - since we'll never want to print data out at this particular spot on the page. Instead, we need a way to pass data, like strings, numbers, and objects, from the controller into the view itself. We also need a good way to get data from the form into the controller.

Let's change our search_user function so it looks like this:

   public function search_user() {
        $uName = $this->post('uName');
        $this->set('uNamePosted', $uName);
    }

And add the line

    <?php echo $uNamePosted; ?>

Above our form.

Now, when we post the form, we should see the name of the user that we posted in the text field show up above our form, because the first line ($this->post()) grabs the data from the post, and the second set() line passes it back to the view. Whatever you pass as the first parameter to set() automatically becomes a PHP variable in your view, with whatever information you place in the second parameter. This information can be a a simple string, or a complex PHP object, or anything in between.

Only displaying data when a method gets run

If you only want the $uNamePosted variable to be displayed in the page when the search_user method is run, change this:

  1. <?php echo $uNamePosted; ?>

To this:

    <?php
    if ($this->controller->getTask() == 'search_user') { 
        echo $uNamePosted;
    }
    ?>

These lines query the controller for the particular task that's being run. When the page is just being shown, the task is "view" by default. But when the form is submitted, we've setup that form to call the "search_user" task, and that information is available from within the $this->controller object, which maps directly to the controller being used on that page. The $this->controller object should be available in every view, all the time.

Using Controllers with Page Types Instead of Single Pages

You'll notice I've been using the word "view" instead of single page throughout this tutorial. That's because view corresponds to any concrete5 page, and single pages are very specific pages. That's the beauty of controllers: they can be used on regular concrete5 page types as well as single pages.

Let's say you've got a page type you're using throughout your site, named "event," and a file named "event.php" within your active theme. But on this event template, you've got a form asking people to RSVP for this event. You can use controllers to separate the logic of that form from the presentation.

  1. Make the form within your event template submit to action('rsvp')?>. You should recognize that this will submit the form back to the current page, and run the rsvp() function within the page type's controller.

  2. Create the controller file here: /controllers/page_types/event.php. Notice, page type controllers live one level below the root. They are given the same filename as the template in the theme.

  3. Place the following code within your page type's controller.

The code:

    <?php
    class EventPageTypeController extends Controller {
        public function rsvp() { }
    }

Whatever you place within rsvp() will automatically be run when that form is submitted. (Note: for this to work, you will have to make sure your page has a valid path.)

Recent Discussions on this Topic

  • View More
  • Ask a Question

MVC question - block development

Would really appreciate your help on a broad "C5 block development" question. Question is: In C5 who puts what code where? View or Controller? (If this has been asked/answered/done, please slap me and point me at the right link; I couldn't find anythin…
Started by olliephillips on 10/14/10 at 5:59 PM

2

replies

Automatic controller function on_before_render not called on page type controllers

I'm not sure why exactly but on_before_render is not getting called automatically when you are in page type controller. Just use the on_start function to, for example, add css stylesheets to the header.
Started by malthoff on 01/14/11 at 6:48 PM

2

replies

Strange behaviour when an 'a' is in the url

I have a single page with actions in the url. So example controller: public function ( $action1, $action2, $action3 ) { ... } One of the actions is a letter like 'A', 'B' etc.. Everything is ok except when using an A in the url, then the va…
Started by MissMarvels on 05/30/11 at 8:33 AM

2

replies

Catching urls with a controller

Hi all, Is it possible to 'catch' urls with a controller? Lets say I have this url: /something/somethingmore/ But there is no page called somethingmore. It's a page I want to create dynamically. So I would like a controller to be called when t…
Started by Ronald72 on 07/15/11 at 6:45 AM

5

replies

Single Page Custom CSS

Hi Guys, I am busy build a custom single page using the mvc architecture. I can not seem to find the best way to include css for this page. I understand that it is the theme's responsibility to make it look pretty, but the styles I am referring to …
Started by jaconel007 on 12/28/11 at 12:03 PM

1

reply

How-To Tags

controller, Model, view, mvc

Related How-Tos

None.

  • Documentation
  • How-Tos
  • Developers
  • Basic MVC in concrete5

Do you have questions

  • What are users saying?
  • Who is using concrete5?
  • What makes concrete5 easy?
  • Why develop on concrete5?
 

We’re on “The Twitter”

RT @toddrankin: looking for feedback/ insight on #concrete5 can anyone provide any?

Follow concrete5

About

  • Try it Out
  • Site Editor Tour
  • Designer Tour
  • Developer Tour
  • Testimonials
  • Showcase
  • History
  • Our Philosophy
  • Credits
  • What does free mean?
  • Blog

Community

  • Members
  • Forums
  • Chat
  • International
  • Jobs
  • eNewsletters

Developers

  • Download concrete5
  • Join Beta Team
  • Translate concrete5
  • Bug Tracker
  • Beta
  • Submit to Marketplace
  • Code Submissions
  • News
  • Community Leaders
  • User Doc Group

Marketplace

  • Add-Ons
  • Themes
  • Installation Help
  • Deal Of The Day
  • Swag

Services

  • Hosting
  • Support Options
  • Consulting
  • Training
  • Enterprise

Documentation

  • Getting Started
  • Editor's Guide
  • Developers Guide
  • How-Tos
  • Basics

Legal

  • Privacy Policy
  • Terms of Use
  • Refund Policy
  • Contact Us
© 2008 to 2012 Concrete CMS Inc. All Rights Reserved.

Sign In?

You must have a user account and be signed to perform this action.

  • Sign In
  • Register