0

I'm working on a little website endeavor and am trying to use jQuery + ajax to dynamically load in information. As of right now I have a home page ~/home and a profile page ~/profile. These two pages share the same header and footer and I load first the header, then the page, then the footer. When I switch pages I just replace the page div with another's html. However the problem here is if you navigate to ~/profile and load it just loads an html page with the page div content.

Basically I'm wondering if anyone has good suggestions on a system to be able to navigate to any link and have the browser know to load the separate header and footer files without hardcoding all of it into each file. I assume it would involve some sort of PHP / framework, but the only one I've worked with CodeIgniter which I am very unexperienced with.

This snippet from here looked promising: CodeIgniter + jQuery(ajax) + HTML5 pushstate: How can I make a clean navigation with real URLs?

if (!$this->input->is_ajax_request())
    $this->load->view('header');

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

if (!$this->input->is_ajax_request())
    $this->load->view('footer');

My only question would be how to have a controller set up that intercepts any link on my domain and loads in the header and footer, with the header file having the linked js file that knows which page to load into the middle via ajax.

Community
  • 1
  • 1

1 Answers1

0

This question is not so simple than you think. It's not just about header and footer, you have mime type changes too. You have to send the html message with text/html, and the ajax message with text/plain content type header. You will need 2 skins/skeletons: one for html, one for ajax call. You'll need a skin provider is able to decide which skin to use in the current situation. You have to render the content independently from the skins, or the skins must call the render method on the content.

It looks very-very roughly like this:

class Controller
{
    public function __construct()
    {
        $provider = new SkinProvider();
        $this->skin = $provider->getSkin();
    }

    public function action()
    {
        $this->skin->render(new Content());
    }
}

class SkinProvider
{
    public function getSkin()
    {
        if ($this->input->is_ajax_request())
            return new AjaxSkin();
        else
            return new HtmlSkin();
    }
}

class AjaxSkin extends AbstractSkin
{
    public function render($content)
    {
        $this->contentType('text/plain');
        $content->render();
    }
}

class HtmlSkin extends AbstractSkin
{
    public function render($content)
    {
        $this->contentType('text/html');
        $this->load->view('header');
        $content->render();
        $this->load->view('footer');
    }
}

class Content extends AbstractView
{
    public function render()
    {
        $data = $this->model->ask();
        $this->load->view('your_view', $data);
    }
}

You can put the constructor of the Controller into and abstract controller, and you will have the actual skin in every controllers you extend from that.

inf3rno
  • 24,976
  • 11
  • 115
  • 197