goncin@wordpress.com:~$ _

Linux, programação e toda sorte de nerdices

Integrando WordPress e Yii Framework: uma nova abordagem

Artigo publicado originalmente em inglês no wiki do Yii
Framework
, em 1º de julho de 2011.

Parece que muitas pessoas andam tentando fazer com que o WordPress e o Yii Framework trabalhem em conjunto. Eu me deparei com o mesmo problema, mas agora creio que o resolvi, após muito quebrar a cuca e gastar inúmeras horas de trabalho.

Meu ponto de partida foi a leitura dos artigos (em inglês) do imasia e do isekream. O princípio de ambas as pesquisas é chamar a aplicação Yii de dentro do WordPress. A solução que proponho coloca-se na mão contrária: utilizar o WordPress como modelo de página para a aplicação Yii, de modo que o usuário final nem perceberá que saiu do primeiro e foi parar na segunda.

Vamos em frente.

No WordPress

Minha instalação do WordPress usa um tema-filho do Twentyten (o padrão do WordPress 3.x). Para os efeitos deste tutorial, assumamos que nossa instalação do WordPress está em http://seuservidor.com.br/wp. Ao aplicá-lo, altere o caminho de acordo com sua situação.

O primeiro passo é criar um arquivo na pasta do seu tema do WP, e chamá-lo yii-template.php.

Arquivo: [raiz-wp]/wp-content/themes/[seutema]/yii-template.php

<?php
/**
 * Template Name: Yii Template
 *
 * Template for Yii-powered pages
 *
 * The "Template Name:" bit above allows this to be selectable
 * from a dropdown menu on the edit page screen.
 *
 * @package WordPress
 * @subpackage Twenty_Ten
 * @since Twenty Ten 1.0
 */
get_header();
?>
 
<div id="container">
  <div id="content" role="main">
 
    <?php
    /*
     * O marcador de lugar abaixo será substituído mais tarde pelo conteúdo gerado pelo Yii.
     */
    ?>
    <!-- ###yii-content-placeholder### -->
 
  </div><!-- #content -->
</div><!-- #container -->
 
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Acabamos de criar um novo modelo para páginas do WordPress.

O passo seguinte é criar uma página no WordPress que use o modelo recém-criado. Acesse o painel administrativo do seu WP, crie uma página e selecione “Yii Template” (deve estar listado) como modelo da página. Informe yiipage no título e deixe o conteúdo da página em branco. Após salvar, você deverá ser capaz de ver a página usando o endereço http://seuservidor.com.br/wp/yiipage.

Isso é tudo o que tínhamos que fazer no WordPress.

No Yii

Crie uma aplicação Yii (usando yiic) sob a raiz da sua instalação do WP, numa pasta chamada yii. Você deverá ver a conhecida página inicial do Yii ao acessar http://seuservidor.com.br/wp/yii.

We’ll need a custom ClientScript class. Let’s create it under [yii-root]/protected/components.

Teremos que criar nossa própria classe ClientScript. Vamos fazê-lo sob  [raiz-yii]/protected/components.

Arquivo: [raiz-yii]/protected/components/ClientScript.php

<?php
 
class ClientScript extends CClientScript {
 
  public function renderHead(&$output) {
    $html = '';
    foreach ($this->metaTags as $meta) $html.=CHtml::metaTag($meta['content'], null, null, $meta) . "\n";
    foreach ($this->linkTags as $link) $html.=CHtml::linkTag(null, null, null, null, $link) . "\n";    
    foreach ($this->cssFiles as $url => $media) $html.=CHtml::cssFile($url, $media) . "\n";
    foreach ($this->css as $css) $html.=CHtml::css($css[0], $css[1]) . "\n";
    if ($this->enableJavaScript) {
      if (isset($this->scriptFiles[self::POS_HEAD])) {
        foreach ($this->scriptFiles[self::POS_HEAD] as $scriptFile) $html.=CHtml::scriptFile($scriptFile) . "\n";
      }

      if (isset($this->scripts[self::POS_HEAD])) $html.=CHtml::script(implode("\n", $this->scripts[self::POS_HEAD])) . "\n";
    }

    if ($html !== '') {
      $count = 0;
      /*
       * A linha abaixo garante que tudo o que for registrado pelo Yii no POS_HEAD irá imediatamente
       * antes do final do cabeçalho (). Dessa forma, os estilos e scripts do Yii serão
       * renderizados *ABAIXO* e *DEPOIS* daqueles do WordPress.
       *
       * A linha original na classe ancestral era assim:
       * $output = preg_replace('/(]*>|)/is', '$1', $output, 1, $count);
       *
       */
      $output = preg_replace('/()/is', '$1', $output, 1, $count);
      if ($count) $output = str_replace('', $html, $output);
      else $output=$html . $output;
    }
  }
 }
?>

Será necessário também sobrepor o método CController.beforeRender(). Isso pode ser feito no arquivo Controller.php, que já existe em [raiz-yii]/protected/components.

Arquivo: [raiz-yii]/protected/components/Controller.php

<?php
/**
 * Controller is the customized base controller class.
 * All controller classes for this application should extend from this base class.
 */
class Controller extends CController
{
    /**
     * @var string the default layout for the controller view. Defaults to '//layouts/column1',
     * meaning using a single column layout. See 'protected/views/layouts/column1.php'.
     */
    public $layout='//layouts/column1';
    /**
     * @var array context menu items. This property will be assigned to {@link CMenu::items}.
     */
    public $menu=array();
    /**
     * @var array the breadcrumbs of the current page. The value of this property will
     * be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
     * for more details on how to specify this property.
     */
    public $breadcrumbs=array();
 
  protected function beforeRender($view) {
 
    /* 
     * Let's prevent Yii from registering jQuery library. We'll stick with
     * the jQuery registered by WordPress.
    */
    Yii::app()->clientScript->scriptMap=array(
      'jquery.js'=>false,
      'jquery.min.js'=>false,
    );
    /*
     * O WordPress trabalha com a jQuery no modo "sem-conflito", i. e., ele não define o apelido $
     * para o objeto jQuery. No entanto, muitos scripts e plugin do Yii supõem que $ aponta para a
     * jQuery, de modo que precisamos fazer essa associação nós mesmos.
     */
    if(! Yii::app()->clientScript->isScriptRegistered('jquery-alias', CClientScript::POS_HEAD)) {
      Yii::app()->clientScript->registerScript('jquery-alias', 'var $ = jQuery', CClientScript::POS_HEAD);
    }

    /*
     * Para manter a coerência visual entre as páginas comuns do WordPress e aquelas turbinadas
     * pelo Yii, devemos utilizar o CSS fornecido pelo tema do WordPress. Contudo, o Yii usa
     * algumas classes CSS específicas para formulários, então é uma boa ideia registrar o
     * arquivo que as contém.
     */
    Yii::app()->clientScript->registerCssFile(Yii::app()->request->baseUrl . '/css/form.css');

    return parent::beforeRender($view);
  }

}
?>

Agora, a pedra fundamental da ideia toda. Vamos alterar o arquivo principal do layout do Yii, para buscar a página do WordPress que preparamos previamente, e substituir o marcador de lugar pelo conteúdo gerado pelo framework.

Arquivo: [raiz-yii]/protected/views/layouts/main.php

<?php
  /*
   * Aqui reside o cerne da mágica. Ao invés de usar o HTML do arquivo principal de
   * layout fornecido pelo Yii, buscamos a página especial do WordPress (como uma string)
   * e substituímos o marcador de lugar pelo conteúdo real.
   */

  echo str_replace('<!-- ###yii-content-placeholder### -->',
    $content, file_get_contents('http://seuservidor.com.br/wp/yiipage'));

  /* NÃO SE ESQUÇA DE APAGAR O CONTEÚDO DA PÁGINA ORIGINAL 😉 */

?>

Por fim, vamos dizer ao Yii para usar nossa classe ClientScript personalizada.

Arquivo: [raiz-yii]/protected/config/main.php

<?php   
    (...)   'components'=-->array(
    /*
     * Vamos usar nosso próprio ClientScript (application.components.ClientScript).
     */
    'clientScript' => array(
      'class' => 'ClientScript'
    ),
  (...)
?>

E isso é tudo. Você deverá conseguir ver sua aplicação Yii com tema WordPress acessando http://seuservidor.com.br/wp/yii, e até mesmo fazer login mediante http://seuservidor.com.br/wp/yii/index.php?r=site/login. Adicionalmente, você pode ajustar sua configuração do Yii para usar URLs de caminho e ocultar o nome do script (assim, seus URLs se parecerão com http://seuservidor.com.br/wp/yii/controller/action). E sim, o AJAX funciona! *__*

De volta ao WordPress, a tarefa final é criar itens de menu (como links) apontando para as páginas turbinadas pelo Yii.

Espero que isto seja tão útil para você quanto foi para mim. Saudações!

7 Respostas para “Integrando WordPress e Yii Framework: uma nova abordagem

  1. Brad 26/09/2011 às 20\0823

    I was able to get Yii and WordPress to share the same *codebase* … Yii does not call WP and WP does not call yii. In fact, you can call anything, like…

    Model::model()->findAll — inside page.php ( WordPress ) and inside Yii get_header() 😀

  2. nomos 18/01/2012 às 05\0546

    have you an example wp-page ?

  3. bezerrath 15/02/2012 às 00\1224

    Muito foda. Até agora atendeu às minhas necessidades.

  4. Pingback: Integração Wordpress e Yii Framework

  5. Anderson 09/10/2014 às 10\1051

    Muito bom seu post.

    Tenho um site em wordPress e uma aplicação YII. Tem alguma idéia para eu desenvolver um login único para as duas aplicações?
    Um abraço!

Deixar mensagem para bezerrath Cancelar resposta