Prerequisite ¶
Install a Wordpress site (mine is in "http://localhost/test/wordpress")
Create a folder where to place an Yii app under wordpress folder (mine is "yii')
Create a new Yii app inside previous folder
Install an WP plugin for including an PHP script (I've used "Include It")
Create a new Wordpress page (mine is "yiitest")
Place inside that page the Yii main script ("[include file=yii\index.php]")
Customize permalinks in WP (mine is "/%post_id%")
Yii preparation ¶
Change "index.php" to override Yii autoload. Kind of hardcoded thing, you have to verify the classes that gives warnings after every new installed plugin in the main page of WP. For a new installation the next code is enough:
<?php
// change the following paths if necessary
$yii=dirname(__FILE__).'/../../path//to/framework/YiiBase.php';
$config=dirname(__FILE__).'/protected/config/main.php';
// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
require_once($yii);
class Yii extends YiiBase
{
public static function autoload($className)
{
$wp_classes = array(
'Translation_Entry',
'Translations',
'NOOP_Translations',
'POMO_Reader',
'POMO_FileReader',
'POMO_StringReader',
'POMO_CachedFileReader',
'POMO_CachedIntFileReader',
'MO',
//'',
);
if(!in_array($className, $wp_classes))
YiiBase::autoload($className);
}
}
spl_autoload_unregister(array('YiiBase', 'autoload'));
spl_autoload_register(array('Yii','autoload'));
Yii::createWebApplication($config)->run();
Change the "main.php" config file inside "componets" key
'assetManager'=>array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..\..\assets',
'baseUrl'=>'yii/assets',
),
'request'=>array(
'class'=>'WPHttpRequest',
'baseUrl'=>'/test/wordpress/yiitest',
'scriptUrl'=>'yiitest',
),
'clientScript'=>array(
'class'=>'WPClientScript',
),
'user'=>array(
'allowAutoLogin'=>true,
),
'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName'=>false,
),
The previously defined components are (credit goes to zaccaria): WPHttpRequest
class WPHttpRequest extends CHttpRequest
{
public function getPathInfo()
{
return $_GET['yiiPath'];
}
}
WPClientScript:
class WPClientScript extends CClientScript
{
public function registerCssFile($url, $media='')
{
wp_enqueue_style( 'stylesheet', $url, array(), '', $media );
}
public function registerScriptFile($url, $media='')
{
wp_enqueue_script( 'script', $url );
}
}
Rewrite URL ¶
I'm using IIS7:
<rule name="captchaRequest" stopProcessing="true">
<match url="yiitest/([A-z_0-9/]+)/captcha/refresh/1$" ignoreCase="true" negate="false" />
<action type="Rewrite" url="yii/index.php?yiiPath={R:1}/captcha&refresh=1" appendQueryString="false" />
</rule>
<rule name="captchaImage" stopProcessing="true">
<match url="yiitest/([A-z_0-9/]+)/captcha/v/([a-z_0-9]+)$" ignoreCase="true" negate="false" />
<action type="Rewrite" url="yii/index.php?yiiPath={R:1}/captcha&v={R:2}" appendQueryString="false" />
</rule>
<rule name="assets" stopProcessing="true">
<match url="yiitest([A-z_0-9/.]+)(css|assets)/([A-z_0-9/.]+)\.(css|js|gif|jpg|png)$" ignoreCase="true" negate="false" />
<action type="Rewrite" url="yii/{R:2}/{R:3}.{R:4}" appendQueryString="false" />
</rule>
<rule name="wordpress" stopProcessing="true">
<match url="yiitest" negate="true" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
<rule name="home" stopProcessing="true">
<match url="(yiitest$|yiitest/$)" ignoreCase="true" negate="false" />
<action type="Rewrite" url="index.php?page_id=5" appendQueryString="false" />
</rule>
<rule name="ajaxResponse" stopProcessing="true">
<match url="yiitest/([A-z_0-9/]+)/ajaxYii/1$" ignoreCase="true" negate="false" />
<action type="Rewrite" url="yii/index.php?yiiPath={R:1}" appendQueryString="false" />
</rule>
<rule name="navigation" stopProcessing="true">
<match url="yiitest/([A-z_0-9/]+)$" ignoreCase="true" negate="false" />
<action type="Rewrite" url="index.php?page_id=5&yiiPath={R:1}" appendQueryString="false" />
</rule>
The order is important but not mandatory. If you don't want to use a certain feature you can identify it by it's name and remove it.
One of the things that you have to keep in mind is for AJAX calls. As an example, for Form AJAX validation I've modified the "action" property of the CActiveForm widget "'action'=>array('', 'ajaxYii'=>true),"
Conclusion ¶
You can have a full Yii app inside a WP page and everything (widgets, AJAX, validation, etc) have to work as expected. The URLRewrite is the key. Check for autoloading issues and JS/CSS duplicates. The two column Yii layout makes some troubles, also you have to play with the layout file (I've removed some of the tags: doctype, html, head, meta, title, body)
Yii as Wordpress Plugin
Wrote an article based on yours. See
Yii as Wordpress Plugin
Her is the link
Yii using Wordpress as page template
That's another solution I found out. I wouldn't accomplish without the work of yours. Thanks!
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.