Você está aqui: Página Inicial Documentação Personalização visual avançada com xdv

Personalização visual avançada com xdv

por Ramiro B. da Luz última modificação 13/11/2011 09:56
Este tutorial demonstra como utilizar temas estáticos em sites Plone usando o collective.xdv.

===============================================================================

 

Personalização visual avançada com o XDV


Este tutorial demonstra como utilizar temas estáticos em sites Plone usando o collective.xdv.


Pré-requisitos
De que você precisa saber para trabalhar com o collective.xdv? 

Coloque os HTML/CSS estáticos em seu pacote de tema
Como adicionar seus recursos estáticos ao tema Plone 

Habilite a transformação do tema
Veja como fazer seu site Plone trabalhar com transformações de tema 

Regras XDV
Quais regras o XDV possui e como elas trabalham 

XPath
Como obter o XPath 

Escrevendo regras
Como compor e utilizar regras ao trabalhar com o rules.xml 

Dicas e truques
Sugestões para tornar sua vida mais fácil ao trabalhar com o collective.xdv

===============================================================================

Pré-requisitos

O que você precisa saber para trabalhar com o collective.xdv?

Se você não está familiarizado com o XDV ou Deliverance, por favor leia a maravilhosa introdução a essas tecnologias feita por Alexander Limi. Se você vai usar o XDV para mais do que simplesmente estilizar o Plone, então este tutorial irá com certeza lhe dar os primeiros passos. Contudo, após lê-lo você também precise ler o capítulo 12 do tutorial do Alexander, escrito por Anne Bowtell. 

Este tutorial será seu guia para aplicar um tema de HTML e CSS estáticos em seu site Plone -- e somente nele -- usando o collective.xdv.

 

Tema estático


Para a parte prática, presumimos que você tenha um tema estático pronto. Isso significa que você criou, comprou ou baixou um conjunto de arquivos HTML e CSS estáticos, até o momento sem nenhuma relação com o Zope ou Plone. Isto é, você deve ser capaz de testar o seu tema estático em um navegador sem que o Plone ou o Zope estejam rodando. 

Nesse tutorial, utilizaremos o pacote xdvtheme.xdvrocks como caso de estudo para a verdadeira implementação. Você provavelmente vai querer baixá-lo e verificar sua pasta static/ para obter o tema estático que nós então iremos converter em um tema Plone real.

Buildout

Como em qualquer projeto Plone, independentemente de ele usar XDV/Deliverance ou não, nós começamos com o buildout. Como não é objetivo deste tutorial detalhar a criação de um buildout, presumimos que você tenha um desses ambientes já configurados com um site Plone padrão. Para referências, consulte o ótimo tutorial escrito por Martin Aspeli sobre o assunto. 

Com o buildout configurado, você deverá adicionar o collective.xdv e suas dependências à mistura:

[buildout]
…
extends =
    …
    http://good-py.appspot.com/release/collective.xdv/1.0   
…   
eggs =
    …
    collective.xdv [Zope2.10]    


Você pode querer usar a opção 'extends-cache' na sua seção [buildout] para baixar localmente todos os recursos da variável 'extends=' a fim de poder usá-los caso esteja eventualmente offline. 

Se você está tentando instalar o collective.xdv para o Plone 4 (Zope 2.12), você pode descartar o trecho [Zope2.10]. Se você usa uma versão anterior do Plone com o Zope < 2.12, a presença desse trecho irá garantir que você possua as funcionalidades do Zope 2.12 requeridas pelo collective.xdv. 

Tais passos devem ser suficientes caso você não esteja em um Mac OS. Esse sistema tem problemas com o pacote binário do lxml de modo que a instalação do collective.xdv no OS X pode ser um tanto quanto problemática. Assim, caso você esteja em um Mac OS seu buildout.cfg deve ser extendedido com mais informações além das acima:

[buildout]
…   
parts =
    lxml
    …
…   

[versions]
lxml = 2.2.2
zc.buildout =
…

[lxml]
recipe = z3c.recipe.staticlxml
egg = lxml    


zc.buildout = pode ser necessário porque a compilação do pacote staticlxml no Mac OS provavelmente irá solicitar uma versão do zc.buildout mais nova do que aquela que você obtém ao criar um ambiente buildout. Essa linha diz que necessitamos da versão mais nova do pacote zc.buildout. 

Após re-executar ./bin/buildout para sua instância e iniciá-la, você deverá ser capaz de adicionar um site Plone pela ZMI com um perfil “XDV Transforms”. Esse procedimento instalará também o perfil “Configuration registry” em seu site. Isso significa que o collective.xdv está instalado e disponível para o Plone. 

Nesse momento, é provável que você deseje temperar seu buildout com suas ferramentas de desenvolvimento favoritas. Opções comuns são os pacotes omelette e plone.reload. Acrescente demais ferramentas a gosto. 

Produto de tema

Qualquer aplicação web precisa saber onde seus arquivos estáticos estão. O XDV não é uma exceção. Em um XDV puro, você pode informar ao seu servidor web para buscar seus arquivos. No caso do collective.xdv, quando você não utiliza tal servidor, um tema Plone padrão ainda é a melhor maneira de informar a um site Plone que existem arquivos no seu tema. Sim, não há nenhuma mágica aqui - você ainda precisa criar no mínimo um produto de tama Plone básico a fim de disponibilizar suas imagens, folhas de estilo, etc. para seu site. Além disso, você realmente vai preferir registrar suas folhas de estilo e javascripts dentro das ferramentas portal_css e portal_javascripts, respectivamente, para aproveitar de suas vantagens tais como cache, mesclagem e assim por diante.


Existe apenas um caso em que você pode evitar criar um tema Plone ao utilizar o collective.xdv - quando tudo que você tem é HTML. Sem imagens, sem folhas de estilo. Contudo não vivemos mais em tempos de puro HTML, sem estilos, sem imagens. Então você não pode evitar de registrar seus recursos. 

A geração de um produto de tema é outro assunto além do escopo deste tutorial. Como foi mencionado, o objetivo aqui é utlizar um tema já pronto, chamado ‘xdvtheme.xdvrocks’. Portanto presumimos que você ou leu o livro “Plone 3 Theming” de Veda Williams, ou leu seu tutorial “How to Create a 
Plone 3 Theme Product on the Filesystem” no plone.org e possui um tema instalável em seu buildout.

A estrutura de nosso tema de exemplo

A essa altura nós temos 3 partes principais com que trabalhar:

  • tema visual estático;
  • produto de tema Plone;
  • buildout com tanto o collective.xdv como seu tema instalados.


===============================================================================

 

Coloque os HTML/CSS estáticos em seu pacote de tema


Como adicionar seus recursos estáticos ao tema Plone

Depois de criar o esqueleto do tema, comece a colocar seus recursos estáticos dentro dele. Existe ao menos 3 maneiras de você fazer isso:

  • Adicione seus recursos à pasta custom/ do seu site Plone. Rápido, pois não requer a geração de um tema Plone. No entanto, esse caminho tem baixo grau de reprodutibilidade e portanto não é o mais recomendado;
  • Adicione seus recursos como componentes do tipo browser resource na pasta browser/. Um método avançado, que no entanto gera URLs feias para seus recursos.
  • Adicione seus recursos à pasta skins/ do seu produto de tema. Fácil e rápido, geralmente envolvendo menos registros do que o método anterior (utilizando a pasta browser/).


Você está livre pra escolher qualquer um desses métodos para adicionar recursos estáticos ao seu site Plone. Mas neste tutorial nós iremos seguir a terceira opção - utilizaremos a pasta skins/ por ser o caminho fácil, uma vez que já possuímos um esqueleto contendo e registrando a mesma. Se você fizer desta maneira, provavelmente você precisará alterar alguns caminhos para seus recursos como as imagens das suas folhas de estilo.

Algumas observações

Pode ser que você deseje adicionar uma nova pasta na sua pasta de skins/ para os seus JavaScripts, por exemplo. O ZopeSkel não gera uma pasta de JavaScripts para você. Se você adicionar tal pasta dentro de skins/, acrescente um registro para a mesma nos arquivos skins.zcml e profiles/default/skins.xml. 

Se você quiser manter os nomes das pastas da forma como eles estão em seu tema estático (ex: images/ ou styles/ etc.), não se esqueça de editar o arquivo profiles/default/skins.xml. 

Se você acrescentar qualquer recurso CSS ou JS, não se esqueça de registrá-lo nos arquivos profiles/default/cssregistry.xml ou profiles/default/jsregistry.xml respectivamente, a fim de poder gerenciá-los por meio das ferramentas portal_stylesheets e portal_javascripts. 

Reinicie sua instância e reinstale o tema para fazer todas as suas alterações tomarem efeito. Uma vez certo de que seu tema está instalado, e de que todos os seus recursos estão disponíveis, você pode começar a escrever as regras de transformação.

===============================================================================

 

Habilite a transformação do tema


Veja como fazer seu site Plone trabalhar com transformações de tema

Quando você possui o collective.xdv instalado em seu site, você obtém uma nova opção de configuração no painel de controle do Plone, intitulada “Theme transform”. É aqui onde você controla as transformações. 

Para começar o trabalho de transformação, você tem de especificar um caminho para a página estática do seu tema (index.html) e o arquivo de regras (rules.xml). O nome dos arquivos realmente não importa, mas geralmente é uma boa ideia seguir convenções. Os campos “Theme template” e 
“Rules file” são responsáveis por essas configurações. Ambos aceitam caminhos relativos para os arquivos correspondentes. Os caminhos iniciam a partir da pasta principal do seu ambiente de buildout. 

Na pasta raiz do seu tema, crie um arquivo rules.xml com o seguinte código:

<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns="http://openplans.org/deliverance">

</rules>    


O arquivo index.html foi colocado em skins/xdvtheme_xdvrocks_custom_templates/ quando nós copiamos o tema estático para dentro do tema Plone. Logo, na configuração “Theme transform”, nós colocamos:

src/xdvtheme.xdvrocks/xdvtheme/xdvrocks/skins/xdvtheme_xdvrocks_custom_templates/index.html


E no campo “Rules file”, informamos:

src/xdvtheme.xdvrocks/xdvtheme/xdvrocks/rules.xml


Após adicionar estes caminhos, você deve explicitamente habilitar as transformações de tema, já que o collective.xdv vem desabilitado por padrão, quando você o instala. Portanto selecione "sim" no campo "Habilitado" e em seguida salve a configuração. 

Já que nosso rules.xml não contém nenhuma regra ainda, você deve agora ver seu site renderizando o HTML não-estilizado do seu tema - até mesmo sem as imagens do seu tema. Nós corrigiremos isso em um momento. Mas para fazê-lo precisamos entender quais regras temos disponíveis e o que essa regras fazem.

===============================================================================

 

Estrutura do tema


A estrutura com que nós iremos trabalhar. Confira o pacote "xdvtheme.xdvrocks" original para verificar por mudanças na estrutura.

<imagem>

===============================================================================

Regras XDV


Quais regras o XDV possui e como elas trabalham

O XDV implementa um conjunto básico de regras que devem solucionar a maioria das necessidades de tematização. As regras serão apresentadas ordem de sua aplicação. 

  • before - copia o(s) elemento(s) especificado(s) a partir do site Plone logo antes do elemento no tema;
  • drop - descarta completamente o(s) elemento(s) seja no Plone ou no tema. Aceita até 2 parâmetros opcionais:
  • content=“” - especifica o(s) elemento(s) a descartar no site Plone. Caso este parâmetro seja especificado, nenhum outro parâmetro na mesma regra é levado em consideração.
  • theme=“” - especifica o(s) elemento(s) a descartar no tema estático.
  • if-content=“” - condição que só funciona junto com o parâmetro theme="". Caso if-content=“” devolva True, o nó especificado em theme="" é descartado da saída. if-content verifica a presença de elementos dentro do site Plone.
  • replace -substitui completamente o(s) elemento(s) do tema com os elementos provenientes do site Plone;
  • prepend - copia o(s) elemento(s) especificado(s) a partir do site Plone para a posição de primeiro filho do elemento no tema;
  • copy - copia o(s) elemento(s) especificado(s) a partir do site Plone para dentro do elemento no tema;
  • append - o mesmo que o prepend, porém o(s) elemento(s) do Plone é(são) copiados para a posição de último filho do elemento no tema;
  • after - copia o(s) elemento(s) especificado(s) a partir do site Plone logo depois do elemento no tema;


Dê uma olhada nas páginas 27-33 da apresentação "From design to Plone site: XDV-driven Plone theming" para uma explicação visual de cada uma das regras. 

Todas as regras exceto copy/replace/drop podem ser aplicadas mais de uma vez para cada elemento no tema. Isso significa que você não pode aplicar duas regras de replace ou de copy ao mesmo elemento no tema. Embora isso não seja uma grande perda - se você precisar fazer isso deve haver algo errado com o seu tema. 

Em geral todas as regras dão suporte à condição if-content, não somente <drop />. Porém usá-la somente em <drop /> deve resolver a maioria dos casos de uso. 

Se mais de uma regra diferente é aplicada para um mesmo elemento do tema, a ordem acima será utilizada e a regra que tiver prioridade mais alta será forçada. Isso significa que se você tiver regras copy e replace para o mesmo elemento do tema, replace será preferida, não importando a ordem em que essas regras estejam declaradas em seu rules.xml. Todas as regras utilizam a versão 1.0 do XPath para especificar elementos.

===============================================================================

Nota do tradutor: vou reescrever esta parte porque hoje é possível fazer seletores somente com CSS.

XPath 

How to get XPath 

XDV uses XPath 1.0 to specify elements on which the transformation should happen. If you donʼt feel comfortable with this, wait until you find out how easy it is to get XPath from a CSS selector. If after this you will still don't feel 
comfortable, you might want to check out Deliverance which allows both XPath and basic CSS selectors for specifying 
elements. Here are some tools you can use. 

Firebug 
One of the easiest ways of getting XPath is to use the Firebug extension for Firefox. 

Pros: 

works in offline mode; 
is already your main (I suppose) debugging tool. 
Cons: 

you need to have two different tabs running your Plone site - one for the site without transformation (by default 
from 127.0.0.1:8080) and another one for the transformed site with the theme applied (by default 
localhost:8080); 
the quality and complexity of XPath returned in this case might be not good enough for your needs. 
Firebug gives XPath for only one particular element that you have clicked. This means it can't give XPath for 
more than one element and can't make it recursive. So, for instance, that doesn't allow you to get XPath for all list items 
in unordered lists. 
CSS2XPath 
Being a CSS person, I prefer getting XPath from CSS selectors. I can construct CSS selectors fully understanding what 
they are supposed to return. So for me getting XPath from a CSS selector is the most advanced, flexible and clear way. Ian 
Bicking wrote an online tool that does exactly that - it converts a CSS selector into XPath - 
http://css2xpath.appspot.com/. 

Pros: 

intuitively clear; 
you work with what you really know; 
the resulting XPath is usually much better than the one from Firebug. 
Cons: 

it is online. 
Python 
You can get the same results as Ianʼs tool gives you but in offline mode. For this you will need to have lxml for Python 
installed. Sounds scary, right? But the good news is - if you have an instance running with collective.xdv you already have 
lxml for your python installed. In your buildoutʼs folder you just need to run 

./bin/zopepy 
You will get a Python prompt that will make all products installed for your instance including lxml (since it is a 
dependency for collective.xdv) available for you. So we can do the following: 

>>> from lxml.cssselect import css_to_xpath 
>>> css_to_xpath("div + p") 
"descendant-or-self::div/following-sibling::*[name() = 'p' and (position() = 1)]" 
Now you can use the returned XPath for specifying elements in your rules.xml.

 

 

 

===============================================================================

 

 

Escrevendo regras

Como compor e utilizar regras ao trabalhar com o rules.xml

No seu arquivo rules.xml adicione:

<replace content='/html/head/title' theme='/html/head/title' />

<drop theme="/html/head/style" if-content="/html/head/style" />
<drop theme="/html/head/script" if-content="/html/head/script" />
<drop theme="/html/head/link" if-content="/html/head/link" />

<append content="/html/head/base" theme="/html/head" />
<append content="/html/head/meta" theme="/html/head" />
<append content='/html/head/style' theme='/html/head' />
<append content='/html/head/script' theme='/html/head' />
<append content="/html/head/link" theme="/html/head" />

 


A primeira regra substitui <title /> em nosso tema estático com o conteúdo real proveniente do Plone. 

O segundo conjunto de regras remove os elementos <style/>, <link/> e <script/> do cabeçalho <head/> de nosso tema, caso o Plone possua os elementos indicados pelos atributos if-content. 

O terceiro conjunto de regras garante que tenhamos tudo o mais que for necessário do <head/> do Plone. 

Agora as imagens. As imagens ainda não renderizam porque nossas folhas de estilo ainda estão tentando obtê-las da pasta ../images. A melhor maneira de fazer as imagens renderizarem em nosso tema Plone é utilizar a função "Localizar e substituir" em nossas folhas de estilo e substituir os caminhos relativos para as imagens por somente seus IDs de forma que o Plone as procure na raiz do site. 

Após fazer isso, seu site Plone deve parecer idêntico ao seu index.html estático. 

Agora podemos de fato mapear o conteúdo do Plone para dentro do nosso tema. 

Primeiro vamos acrescentar algumas coisas úteis ao nosso <body />

<prepend theme="/html/body" content="/html/body/@class" />
<prepend theme="/html/body" content="/html/body/@id" />    
<prepend theme="/html/body" content="/html/body/@dir" />


Agora vamos acertar o link do logo e mais algumas coisinhas

<prepend content="//*[@id='portal-logo']/attribute::href"
    theme="//*[@id='logo']/a" />
<prepend content="//*[@id='portal-logo']/attribute::accesskey"
    theme="//*[@id='logo']/a" />
<prepend content="//*[@id='portal-logo']/img/attribute::title"
    theme="//*[@id='logo']/a" />


Com as linhas acima, nós linkamos o logo à raiz do site e geramos algumas funcionalidades de usabilidade e acessibilidade. 

Agora que tal substituir as "ações do site" com algo mais útil:

<replace content="//*[@id='portal-siteactions']"
    theme="//*[@id='portal-siteactions']" />


... e copiar os itens da navegação global para dentro do nosso tema:

<copy content="//*[@id="portal-globalnav"]/li"
    theme="//*[@id="global-navigation"]/ul" />


Agora vamos popular as colunas com portlets reais. No tema de exemplo, temos apenas uma coluna - a correta. Mas também temos portlets localizados abaixo do conteúdo. Então, para simplificar, iremos popular os portlets inferiores com os portlets provenientes da coluna esquerda do Plone:

<drop theme="//*[@id='bottom-portlets']"
    if-content="not(//*[@id='portal-column-one']/div[@class='visualPadding']/*)"/>
<drop theme="//*[@id='column']"
    if-content="not(//*[@id='portal-column-two']/div[@class='visualPadding']/*)"/>

<copy content="//*[@id='portal-column-one']/div[@class='visualPadding']/*"
    theme="//*[@id='bottom-portlets']" />
<copy content="//*[@id='portal-column-two']/div[@class='visualPadding']/*"
    theme="//*[@id='column']" />


O primeiro conjunto utiliza regras muito poderosas - drops condicionais. Lembre-se da diferença entre as regras drop: O drop comum descarta elementos desnecessários do Plone, mas o drop condicional remove o elemento do tema se a saída do atributo 'condition' for verdadeira (True). 

Assim, utilizando regras condicionais, evitamos renderizar as colunas caso o Plone não nos forneça nenhum portlet para as mesmas. 

O segundo conjunto de regras copia os portlets do Plone para nosso tema. 

Agora vamos substituir o rodapé estático com aquele gerado pelo Plone:

<copy content="//*[@id='portal-footer']/*" theme="//*[@id='footer']" />
<append content="//*[@id='kss-spinner']" theme="/html/body" />


Também adicionamos o spinner - o gif animado que gira enquanto você espera algum processamento do Plone. Por exemplo, quando você salva um documento e demora um pouco para carregar o formulário de edição. A regra append acrescenta o spinner como último filho da tag <body/>. 

Finalmente, vamos substituir nosso conteúdo falso com aquele vindo do Plone:

<copy content="//*[@id='portal-column-content']/*"
    theme="//*[@id='document']" />


Basicamente é isso. Pode ser uma boa verificar o rules.xml do exemplo para ver regras adicionais utilizadas para dar o polimento final ao trabalho.

===============================================================================

 

Dicas e truques


Sugestões para tornar sua vida mais fácil ao trabalhar com o collective.xdv

z3c.jbot

Enquanto o XDV transforma a aparência de uma página, o conteúdo em si continua sendo administrado pelo Plone. Se você quiser modificar alguma informação proveniente do Plone, você provavelmente precisará personalizar o template ao nível do Plone, como você faria em um tema Plone comum. 

Personalizar templates Plone pode não ser tão divertido. Porém o z3c.jbot (que simplesmente significa “Just a Bunch Of Templates”) pode auxiliar nesse processo. Não iremos mergulhar nos detalhes de como instalar esse pacote - você pode descobrir isso na página do produto. Esse pacote irá adicionar alguns poucos milisegundos ao tempo total de carregamento da página, mas pode bem valer a pena. 

Com o z3c.jbot você pode sobrescrever praticamente qualquer recurso ou template no Plone não importando se ele está associado a um portlet, view, viewlet ou qualquer ZPT normal.

Altere o DOCTYPE.

A saída do collective.xdv é XHTML 1.0 Transitional por padrão. Você não pode "ler" o Doctype a partir do index.html do seu tema no momento. Às vezes vocẽ pode querer alterá-lo para outro Doctype se seu tema precisar disso. Por exemplo, você quer ter o XHTML Strict. 

Para isso, você precisa sobrescrever o código padrão que vem do XDV. Sobrescrever o template inteiro é uma má ideia porque você precisará ajustar tal código toda vez que o XDV for atualizado. Por isso o collective.xdv permite você "extender" o XDV padrão. Para fazer isso, você precisará escrever XSLT, porém algo bem simples e aqui temos um exemplo para você. 

Para sobrescrever o Doctype (ou francamente qualquer saída do XDV), crie um arquivo chamado extra.xsl na pasta raiz do seu tema com o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output
      doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
      doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
</xsl:stylesheet>
    


Isso resultará em <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

Uma vez que você tenha o extra.xsl em seu tema, você deve informar às transformações XDV saberem onde estão suas extensões. Vá até a configuração “Theme transform” e adicione

src/xdvtheme.xdvrocks/xdvtheme/xdvrocks/extra.xsl


no campo “XSLT extension file”. Isso resultará em uma saída HTML com o Doctype especificado. 

Para saída compatível com XHTML é necessário utilizar os doctypes XHTML1.0 transitional ou strict. Nenhum outro doctype irá disparar o modo de compatibilidade no serializador XML. 

Para saída compatível com HTML 5, o uso do doctype XHTML1.0 strict é recomendado, já que ele é uma "string doctype obsoleta, mas permitida".

Tema Plone com XDV em uma máquina virtual

Se você está usando uma máquina virtual qualquer para testar seu tema em diferentes sistemas operacionais e navegadores, muito provavelmente sua máquina virtual irá tentar acessar seu site utilizando um IP específico. Nesse caso, você pode se deparar com a situação em que seu site Plone não recebe as transformações aplicadas quando visualizadas a partir da máquina virtual. Para resolver isso, simplesmente acrescente tal IP (com a devida porta) ao campo "Domains" da configuração “Transform settings”.

Acesso à ZMI

É sempre uma boa ideia manter a ZMI do seu site em um domínio separado ou acessá-la por IP a fim de evitar que as transformações lhe sejam aplicadas.