Yii 1.1: Integrating Wordpress and Yii,Working Out The Details.

14 followers

Overview

This article is based on fr0d0z's article Integrating Wordpress and Yii: still another approach, using Yii as the router/controller and provides more details on how to set up this integration.To be more specific,the idea is not to use any main.php layout in Yii's controllers.This gives the advantage that we do not need to modify any Yii code when we switch a theme in WordPress admin panel,provided we have done a very basic setup which I explain below.

WordPress Setup

First things first,follow the instructions in fr0d0z's article to set up WordPress.Regarding the WpController,I did not use an index view.So the code for WpController is

class WpController extends Controller
{
    public function init()
    {
     // note that we disable the layout
        $this->layout = false;
        parent::init();
    }
 
    public function actionIndex()
    {   
        try {
            wp();
            require_once(ABSPATH . WPINC . '/template-loader.php');
            Yii::app()->end();
        }
            // if we threw an exception in a WordPress functions.php
            // when we find a 404 header, we could use our main Yii
            // error handler to handle the error, log as desired
            // and then throw the exception on up the chain and
            // let Yii handle things from here
 
            // without the above, WordPress becomes our 404 error
            // handler for the entire Yii app
        catch (Exception $e) {
            throw $e;
        }
    }
}
?>

Setting Up A Theme Template For Yii

Next we do a very simple set up for the template Yii will use in Wordpress to wrap the controller views.This is replacing Yii's main.php layout.To do that,we locate a generic template in Wordpress theme's folder that includes the header and footer.Let's take for example the twentyeleven theme,the page.php template is simply

<?php
get_header(); ?>
   <div id="primary">
    <div id="content" role="main">
        <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'content', 'page' ); ?>
         <?php comments_template( '', true ); ?>
         <?php endwhile; // end of the loop. ?>
      </div><!-- #content -->
     </div><!-- #primary -->
<?php get_footer(); ?>

The loop ouputs the main content for Wordpress and it will be replaced by Yii's output. So make a copy of this page.php file,rename it as page-yii.php,and save it in the same folder as page.php,(theme's root). Then replace the loop with

<?php $this->renderPartial($view,($params)?$params:null); ?>

So page-yii.php looks like:

<?php
get_header(); ?>
    <div id="primary">
    <div id="content" role="main">  
             <?php   $this->renderPartial($view,($params)?$params:null);  ?>
     </div><!-- #content -->
     </div><!-- #primary -->
<?php get_footer(); ?>

Define An Alias For WordPress Themes Folder

In config/main.php:

'aliases'=>array(
      ...
    'wp_themes'=>'webroot.wp.wp-content.themes',
      ...
    ),

Setting Up Yii Controllers

In SiteController disable the main layout in init().

public function init(){
       $this->layout=false;
       parent::init();
    }

In actionIndex replace

$this->render('index');

with

$this->render('wp_themes.'.get_template().'.page-yii',array('view'=>'index'));

get_template() is a Wordpress function.Surreal,we are inside a Yii controller,right?But Wordpress has already "started" since Yii's bootstrap script index.php ran,it just has not rendered a template,so it's possible to use this function.It simply returns the Wordpress activated theme folder name.In our case it's just "twentyeleven" string.So render function will find our page-yii.php template that we wrote earlier,and it will pass 'index' as value for the view parameter. Inside page-yii.php,we are still in SiteController's scope (surreal again!) so we can use $this->renderPartial to render the index view (passed as view parameter).

<?php  $this->renderPartial($view,($params)?$params:null); ?>

and so the content of site/index.php view file will be wrapped in WordPress layout.

In the same manner,in actionLogin():

$this->render('wp_themes.'.get_template().'.page-yii',array('view'=>'login','params'=>array('model'=>$model)));

and in actionContact():

$this->render('wp_themes.'.get_template().'.page-yii',array('view'=>'contact','params'=>array('model'=>$model)));

For the static views we need a new StaticViewAction that extends CViewAction and overrides only the run() function :

class StaticViewAction  extends CViewAction
{
 
    public function run()
    {
        $this->resolveView($this->getRequestedView());
        $controller=$this->getController();
        if($this->layout!==null)
        {
            $layout=$controller->layout;
            $controller->layout=$this->layout;
        }
 
        $this->onBeforeRender($event=new CEvent($this));
        if(!$event->handled)
        {
            if($this->renderAsText)
            {
                $text=file_get_contents($controller->getViewFile($this->view));
                $controller->renderText($text);
            }
            else
           //We only changed the following line
          $controller->render('wp_themes.'. get_template() .'.page-yii',array('view'=>$this->view));
          $this->onAfterRender(new CEvent($this));
        }
 
        if($this->layout!==null)
            $controller->layout=$layout;
    }
}

We have only replaced the render path from the parent class run() function. Save the above class as StaticViewAction.php in components folder. Next,make sure the action is declared in SiteController's actions() function.

public function actions()
    {
      // page action renders "static" pages stored under 'protected/views/site/pages'
      // They can be accessed via: index.php?r=site/page&view=FileName
       'page'=>array(
            //'class'=>'CViewAction',we replace this
                  'class'=>'StaticViewAction',
            ),
        );
    }

And this is enough to render in Wordpress all the static view files you place in views/site/pages,like about.php for example. Because of this setup,as we mentioned in the beginning,if we change theme in Wordpress admin panel,the Yii views will still be rendered without changing any Yii code,(of course we should have created a page-yii.php file in every theme we want to activate).Please note that when you change themes back and forth,certain configurations are lost like widgets in sidebars or the menu used-this is Wordpress related issue.In this case you just re-configure. Last,go to WordPress admin panel in Appearance > Menus and add the Yii actions as custom links,to make them appear in the menu.For the login action,you can use in page-yii.php the code that displays a Login or Logout link based on whether the user is logged in or not,(see demo).

Conclusion

It's great to be able to use Yii fused with WordPress for things like blogging and Media management.Sure you could code a CMS for blogging in Yii,but chances are you can't compete with thousands of manhours that developers have spent on WordPress over the years.So it's best to leave that for WordPress and use Yii for backend management of business related critical data,like products,personell etc. As a matter of fact,since it's possible to use Yii code inside Wordpress plugins it would be a good idea to code wordpress plugins that manage data handled by Yii,with an interface rendered inside the WordPress admin panel. In addition,a gazillion WordPress themes are available both free and commercial ready to dress up your Yii application.

Resources

Total 4 comments

#15885 report it
kiran.irali at 2013/12/26 08:03am
SiteController cannot find the requested view "wp_themes.twentyeleven.page-yii"

Soln- main.php

$wpt=dirname(dirname(dirname(dirname(FILE)))); // this will give you the / directory Yii::setPathOfAlias('wpt', $wpt);

return array( ..... ..... 'aliases'=>array( 'wp_themes'=>'wpt.wp-content.themes', ), ..... ..... );

#12148 report it
Dhamodharan R at 2013/03/01 06:38am
Exception

I got the below error while trying above steps

SiteController cannot find the requested view "wp_themes.twentyeleven.page-yii"

Please help me and do a favour for me.

Thanks

#9659 report it
drumaddict at 2012/09/01 07:47pm
Thanks!

Actually you did all the hard work,I consider my article just adding more details to your article. Admin WordPress Plugins coded in Yii is the main thing to look forward to,now! Sure,no need to ask,update your article as you wish.It's best for the parent article to include all the contributions.My only concern is if more people contribute,your article will turn into one big lengthy monster!

#9658 report it
acorncom at 2012/09/01 07:32pm
Nice work

Those are quite useful additions to what I worked out. Love to see if we can work out an easy way to handle admin plugins now :-)

I'll probably update my article to point to yours for further thoughts. What do you think about tweaking my article to contain your thoughts as well? Seems like it might be handy to have one, definitive wiki article as the place for all this info. Do you want to make the tweaks there too? We should put some sort of "Contributors" section up near the top so everyone who is working on this gets credit for their input. Thoughts?

Leave a comment

Please to leave your comment.

Write new article
  • Written by: drumaddict
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +8
  • Viewed: 16,912 times
  • Created on: Sep 1, 2012
  • Last updated: Oct 22, 2012
  • Tags: wordpress