Tags: tutorial

Criação de skins para b2evolution: os primeiros passos

b2evolution Enviar feedback »

Nesse tutorial, vamos criar um skin muito básico para o b2evolution. Na verdade, vamos transformar um template já existente em um skin.

Por sugestão do Eliazer, vou usar o template "The Perfect 'Blog Style' 3 Column Liquid Layout (Percentage widths)". Como ele é extremamente simples, podemos ter um mínimo de certeza que o css não atrapalhará nosso trabalho. ;)

O primeiro passo é criar uma pasta para o skin dentro da pasta skins do b2evolution. A pasta que eu criei para esse skin se chama layout_3col.

O arquivo que o b2evolution procura para o skin, por padrão, chama-se index.main.php Em um post futuro, eu mostrarei como funciona a hierarquia de templates do b2evolution. Por hora, ter o arquivo index.main.php no template será o suficiente.

Copie e cole o conteúdo do template que queremos adaptar no arquivo index.main.php. Após isso, instale o skin no painel de administração, e configure algum blog para usar esse skin. Você vai ver que ficou com uma cópia do template original, o que não é muito útil. Isso porque agora precisamos 'rechear' o nosso skin com as tags de template do b2evolution.

O primeiro passo é fazer a inicialização do skin. Isso é feito chamando a função: skin_init( $disp ) no início do skin.

Para isso, podemos colocar no início do skin a seguinte tag, antes mesmo do início do html:

PHP:

<?php
skin_init$disp );
?>

Essa variável, $disp, indica o modo de visualização com o qual estamos trabalhando no momento. Por exemplo, podemos estar usando a visualização de uma página ($disp='page'), a visualização de um post ($disp='single') ou a visualização de uma lista de posts ($disp='posts'). No futuro, veremos como usar isso para criar detalhes ou até mesmo templates diferentes para as diferentes visualizações.

Agora, vamos começar a colocar as tags de template dentro da div css com id col1.

O bloco básico a ser colocado:

PHP:

<?php
        // --------------------------------- INÍCIO DOS POSTS ----------------------------------
        // Mostra mensagem se não houver post:
        display_if_empty();
        while( $Item = & mainlist_get_item() )
        {
            // ------------------------------ SEPARADOR DE DATAS ----------------------------
            $MainList->date_if_changedarray(
                        'before'      => '<h3>',
                        'after'       => '</h3>',
                        'date_format' => '#',
                    ) );
            echo '<h2>';
            $Item->title();
            echo '</h2>';
            // ---------------------- CONTEÚDO DO POST ----------------------
            skin_include'_item_content.inc.php',  array(
                    'image_size'    =>    'fit-400x320' ) );
            // -------------------------- CONTEÚDO DO POST -------------------------
            echo 'Postado na categoria: ';
            $Item->categories();
            echo '<br /> Tags';
            $Item->tags();
            echo '<br />';
            $Item->feedback_linkarray('type' => 'comments') );
            // ------------------ FEEDBACK (COMMENTS/TRACKBACKS) INCLUSOS AQUI------------------
            skin_include'_item_feedback.inc.php');
            // ---------------------- FIM DOS COMENTÁRIOS (COMMENTS/TRACKBACKS) ---------------------
            echo '<hr />';
 
        } // ---------------------------------- FIM DOS POSTS ------------------------------------
?>

display_if_empty() irá mostrar uma mensagem se aquele tipo de visualização não tiver nenhum posts.

Após isso, começa o loop padrão do b2evolution. Como o b2evolution é orientado a objetos, o que você obtém é um objeto do tipo Item.

A forma básica desse loop é a seguinte:

PHP:

while( $Item = & mainlist_get_item() )
{
    //faz alguma coisa com cada item (post)
}

Após o início do loop, existe uma chamada ao método date_if_changed do objeto $Mainlist. Esse método irá exibir a data dos posts sempre que a data mudar, ou seja, se você tiver 3 posts numa mesma data, será exibido a data, seguida pelos 3 posts, seguida pela data do próximo post. (Ou seja, a data não será exibida 3 vezes).

Logo após, exibimos o título do post:

PHP:

echo '<h2>';
$Item->title();
echo '</h2>';

O conteúdo do post é exibido pela inclusão de outro arquivo:

PHP:

// ---------------------- CONTEÚDO DO POST ----------------------
skin_include'_item_content.inc.php',  array(
        'image_size'    =>    'fit-400x320' ) );
// -------------------------- CONTEÚDO DO POST -------------------------

De onde vem esse arquivo que estamos incluindo? Vejamos: como o nosso skin não possui um arquivo chamado _item_content.inc.php, por padrão, o b2evolution procura um arquivo com esse nome na pasta /skins, e lá o encontraremos. Antigamente, existia uma função chamada $Item->content() que fazia a exibição do conteúdo do post, mas atualmente essa função está marcada como obsoleta no código, e se você a incluir, no final das contas, ela tentará incluir o arquivo _item_content.inc.php .

Podemos simplesmente aproveitar o arquivo _item_content.inc.php fornecido pelo b2evolution, ou se acharmos que precisamos de personalizá-lo ainda mais, podemos copiá-lo para a pasta de nosso skin e fazer as personalizações necessárias.

Após isso, incluímos no skin as categorias e as tags de cada post:

PHP:

echo 'Postado na categoria: ';
$Item->categories();
echo '<br /> Tags';
$Item->tags();
echo '<br />';

Depois disso, incluímos um link para o visitante do blog incluir comentários:

PHP:

$Item->feedback_linkarray('type' => 'comments') );

E como queremos que quando o visitante clicar nesse link ele realmente veja o formulário de comentários, podemos fazer a inclusão do formulário de uma forma muito fácil:

PHP:

// ------------------ FEEDBACK (COMMENTS/TRACKBACKS) INCLUSOS AQUI------------------
skin_include'_item_feedback.inc.php');
// ---------------------- FIM DOS COMENTÁRIOS (COMMENTS/TRACKBACKS) ---------------------

Novamente, se quisermos personalizar o formulário de comentários, podemos copiar o arquivo _item_feedback.inc.php para o nosso template e editarmos a nossa cópia.

Por questões de simplicidade, incluí um <hr /> como separador de cada post. O mais correto fosse criar uma div para cada post, mas assim já temos uma separação visual entre um post e outro.

Pronto! Já temos um skin básico para o b2evolution!

Quer dizer, mais ou menos né? Isso porque as nossas duas barras laterais e os menus superiores ainda trazem o texto 'placeholder' que veio do template que copiamos. Para isso, precisaremos lidar com o conceito de contâineres e widgets, o que veremos na próxima seção desse tutorial.

Anexos:

Criando plugins para b2evolution - um renderizador de texto

plugins 2 feedbacks »

A maioria (se não todos) os CMS faz algum controle de quais tags podem entrar em um texto ou em um comentário. O b2evolution usa um validador de XHTML, para que seu plugin seja HTML válido, e não permite que vc use algumas tags, como por exemplo, object e embed. Você pode desabilitar a validação, mas isso não é a opção mais interessante. Você pode incluir objetos flash através de um plugin!

Digamos, por exemplo, que queiramos incluir alguma apresentação do slideshare. Ao lado de cada slide, em "Embed", o slideshare dispõe de um código para copiar e colar no seu site. Mas se o seu validador de xhtml do b2evolution estiver habilitado, a tag object será considerada ilegal (fora outros erros relacionados a style, vai depender da sua configuração).

No slideshare, ao lado do código para ser copiado no site, tem um link chamado 'customize', onde existe um código "for Wordpress", que podemos postar sem problemas no b2evolution, mas não fará com que os slides sejam exibidos:

 [slideshare id=380143&doc=django-096-1209509342005285-9&w=425] 

Usando um plugin, podemos fazer com que o b2evolution entenda esse código e o transforme numa apresentação. Para isso, vamos criar um plugin renderizador de texto.

Vamos chamar nosso plugin de presentation plugin (poderíamos chamar de slideshare plugin, mas queremos que ele suporte outros sistemas de publicação de slides no futuro). Seguindo as indicações na primeira parte do tutorial, vamos criar na pasta plugins uma pasta chamada presentation_plugin, e dentro dela um arquivo chamado _presentation.plugin.php. Para ganhar tempo, podemos copiar o skeleton.plugin.php para presentation_plugin/_presentation_plugin.php (os nomes dos arquivos são padronizados para que o b2evolution encontre os plugins, por isso é importante seguir isso corretamente!)

Vamos começar a fazer nosso plugin. Primeiro precisamos mudar o nome da classe e preencher as variáveis que deverão ser sobrescritas:

PHP:

class presentation_plugin extends Plugin
{
    /**
     * Variables below MUST be overriden by plugin implementations,
     * either in the subclass declaration or in the subclass constructor.
     */
    var $name 'Presentation';
    /**
     * Code, if this is a renderer or pingback plugin.
     */
    var $code 'evo_presentation';
    var $priority 50;
    var $version '0.1-dev';
    var $author 'http://example.com/';
    var $help_url '';
 
    var $apply_rendering 'opt-in';

Depois, precisamos substituir o PluginInit (o 'construtor' do Plugin)

PHP:

function PluginInit( &amp;amp$params )
    {
        $this->short_desc $this->T_('Presentation Plugin');
        $this->long_desc $this->T_('Presentation Plugin for b2evolution. Supports slisdhare and ...');
    }

Um plugin renderizador de texto deve implementar o método RenderItemasHtml. Vamos lá!

PHP:

function RenderItemAsHtml$params )
    {
        $content $params['data'];
        $params['data'] = callback_on_non_matching_blocks$content'~(<(code|pre)[^>]*>.*?</\2>)|(<[^>]+?>)~is'array($this,'render_slideshare' ));
        return true;
    }

callback_on_non_matching_blocks é uma função do b2evolution e irá aplicar uma função de substituição de textos em todo o trecho que NÃO casar com uma determinada regex. Com essa regex, estamos definindo que não queremos que o texto dentro de tags code, pre, e dentro de definições de tags sejam afetados pelo método render_slideshare. (Valeu Yabba pela ajuda com a regex!). Vamos agora ao método render_slideshare do objeto:

PHP:

function render_slideshare($text)
    {
        $regex "#\[slideshare(.+?)\]#is";
        $new_content preg_replace_callback$regexarray($this,'slideshare_replacer'), $text );
        return $new_content;
    }

Mais uma regex, para casar o texto do slidshare e efetivamente fazer a substituição, no método slideshare_replacer.

PHP:

function slideshare_replacer $matches 
    {
        $slideshare html_entity_decode($matches[1]);
        $slidevars array();
        parse_str($slideshare,$slidevars);
 
        $height $slidevars['w']/1.22;
        $res        '<object style="margin:0px" width="'.$slidevars['w'].'" '.'height="'.$height.'"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc='.$slidevars['doc'].'"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc='.$slidevars['doc'].'" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="'.$slidevars['w'].'" '.'height="'.$height.'"></embed></object>';
        return $res;
    }

A forma com que o slideshare gera o texto para publicação facilitou as coisas: usando a função parse_str do php eu consigo transformar os parâmetros (id=380143&doc=django-096-1209509342005285-9&w=425) em um hash. Aí, foi só gerar o texto da tag object.

Como queremos que nosso slide seja exibido também em feeds, precisamos escrever o método RenderItemAsXml. Felizmente, isso é bem simples:

PHP:

function RenderItemAsXml$params )
    {
        return $this->RenderItemAsHtml$params);
    }

Nosso plugin está pronto! Agora, basta selecionar o "Presentation" nos renderizador de texto ao publicar sua apresentação do slideshare! Se você quiser dar uma olhada em como fica o plugin pronto, você pode baixar o arquivo.

O resultado: [slideshare id=380143&doc=django-096-1209509342005285-9&w=425]

Mais ainda há mais o que fazer. Na próxima parte do tutorial, vamos ver como usar as ferramentas que o b2evolution para criar configurações para o nosso plugin! Veja a parte 1!

Criando plugins para b2evolution - introdução

plugins Enviar feedback »

Como é de praxe em sistemas gerenciadores de conteúdo, o b2evolution tem alguns pontos onde pode ter o seu comportamento alterado ou funcionalidades adicionadas pelo uso de plugins.

A pasta para a instalação de plugins é, coincidentemente, a pasta plugins :)

Para escrever um plugin para o b2evolution, é preciso estender a classe plugin. Existe um arquivo chamado skeleton.plugin.php , que você pode usar como modelo para o seu primeiro plugin. A classe do plugin deve se chamar nomedoplugin_plugin e o arquivo deve se chamar _nomedoplugin.plugin.php. Se o seu plugin contiver vários arquivos além da classe PHP, você pode incluí-lo dentro de uma pasta chamada nomedoplugin_plugin.php, ficando a seguinte hierarquia:

plugins/nomedoplugin_plugin/_nomedoplugin.plugin.php

Vamos dar uma olhada no cabeçalho do skeleton.plugin.php:

class pluginname_plugin extends Plugin
{

      /**
       * Variables below MUST be overriden by plugin implementations,
       * either in the subclass declaration or in the subclass constructor.
       */


      var $name = 'PLUGIN_NAME';

      /**
       * Code, if this is a renderer or pingback plugin.
       */


      var $code = '';
      var $priority = 50;
      var $version = '0.1-dev';
      var $author = 'http://example.com/';
      var $help_url = '';
      var $apply_rendering = 'opt-in';

O code é um texto usado para identificar o seu plugin internamente, é e usado com os plugins renderizadores. priority é a prioridade de seu plugin. No caso de uma mesma ação disparar diversos plugins, será disparado primeiro o plugin com menor prioridade. version é, sem segredo, a versão do seu plugin. author é um link para o site do desenvolvedor do plugin, help_url é um link para uma página que contenha a documentação do plugin. apply_rendering diz respeito a aplicação de plugins renderizadores de texto e de que forma eles serão aplicados.

Plugins renderizadores de texto

Plugins renderizadores de texto são plugins que modificam o texto que você escreveu de alguma forma. Exemplos de plugins renderizadores são o plugin de smilies, que transforma seus smilies em imagens, o auto_p, que transforma quebras de linhas em parágrafos. Você pode escolher post a post quais plugins você renderizadores você quer que sejam aplicados a esse post, e a váriavel apply_rendering em cada plugin especifica como isso será exibido na tela de edição de posts:

  • stealth: é sempre usado, mas não é exibido como uma opção
  • always: é sempre usado e exibido como um checkbox desabilitado
  • opt-out: habilitado por padrão
  • opt-in: desabilitado por padrão
  • lazy: checkbox é exibida, mas desabilitada
  • never: não pode ser usado como um renderizador

Para quem tem experiência com o wordpress, um plugin renderizador é de certa forma semelhante a um plugin do wordpress que filtre o "the_content".

Um plugin renderizador deve implementar um dos seguintes métodos: RenderItemAsHtml, RenderItemAsXml, DisplayItemAsHtml, DisplayItemAsXml. Os dois primeiros (que começam com Render) são salvos em cache e portanto, são aplicados apenas na primeira vez que o item é exibido. Os dois últimos, que começam com Display, são aplicados todos as vezes que o item é exibido, e sua saída não é salva no cache. RenderItemAsHtml e DisplayItemAsHtml se aplicam a visualização html do item, RenderItemAsXml e DisplayItemAsXml são usados na exibição xml do item (por exemplo, na exibição de um feed rss). Assim, é possível exibir elementos apenas na visualização comum do post, eliminando do rss items que não façam sentido num leitor de feeds, ou o contrário, exibir alguma coisa apenas no feed e não no blog.

Como exercício para o leitor, sugiro dar uma olhada nos plugins que já vem com o b2evolution, no próximo artigo mostrarei um exemplo de um plugin renderizador completo!

Veja a parte 2 do tutorial

Contato. ©2010 by Walter Cruz. Design & icons by N.Design Studio. Skin by Tender Feelings / Evo Factory.