Verificando se tem imagem na notícia do Plone
Este artigo mostra de forma fácil como verificar se uma notícia tem ou não uma imagem atrelada a ela, isso é muito útil pois evita o uso abusivo do método getObject() , este método usado constantemente principalmente em áreas do site com muito acesso simplesmente reduz e muito a performance do seu portal.
O que iremos fazer?
Iremos criar nosso próprio método (função) que verifica se tem ou não a imagem, depois iremos registrar esse método no catálogo do plone, dessa forma sempre que chamamos os brains (cérebros) do catálogo este método de verificação de imagem virá também.
Mãos a obra!
Entre na ZMI no local onde guarda seus scripts python, se você não tem este lugar entre na pasta custom mesmo, http://seu-site.com.br/portal_skins/custom/manage_workspace
Clique no menu de adição, escolha a opção "Script Python" e clique em add.
Digite o nome do seu método/função, afinal scripts python são isso métodos/funções que podem ser chamados em vários contextos diferentes, e por isso usaremos ele no catálogo.
No corpo do seu script python você colocará o seguinte código:
# Este código verifica se um objeto tem ou não imagem return bool(context.getImage())
Este código verifica se o atributo Image esta preenchido ou não ou seja se tem imagem anexada ou não, o legal é que este código serve tanto para o objeto News Item quanto para o Image já que os dois usam o mesmo campo imagem, caso você queira restringir somente para notícias do plone use este código abaixo:
# Este código verifica se o objeto do tipo News Item tem ou não imagem if context.portal_type == 'News Item': return bool(context.getImage()) return False
Potal Catalog
Vamos ao portal catalog registrar um novo índice para armazenar a informação em cada brain (cérebro do catálogo) entre no seguinte endereço em seu site http://seu-site.com.brt/portal_catalog/manage_workspace e clique na aba Indexes.
Como o campo que pretendemos buscar é um field vamos marcar a opção FieldIndex no menu, clique em add.
O campo Id será o nome do método usado quando chamar o catalogo, o campo Indexed Attributes será o método/função que chamaremos, então basta colocar o nome do script python que criamos, no meu caso eu coloquei o nome de verifica_img_noticia tanto no Id quanto no Indexed Attributes para não confundir depois, não é necessário colocar .py no final.
Repare que nosso índice esta com o número zero no final, isso significa que não tem nenhum objeto com o critério que fizemos, por isso devemos re-indexar nossos objetos para pegarem o novo critério.
Então sempre que criar uma nova notícia terei que ir ai la e re-indexar?
Não, isso é feito apenas uma vez para que os velhos objetos reconheçam o novo field, mas novos objetos automaticamente pegarão esta nova definição que fizemos.
Como sei se meu critério esta pegando realmente a informação correta?
Simples, clique no seu field, e em seguida na aba browser, ele mostrará os objetos que tem imagem e os que não tem, legal né.
Não gostei da parte do script python tenho que mesmo fazer tudo isso?
É nesse caso sim!, mas se tivesse um método nos objetos que retornasse exatamente o que nosso script faz, bastaria chama-lo, quer um exemplo digamos que você quer saber quais pastas estão marcadas como excluídas da navegação, basta criar um FieldIndex e no campo id e atributo coloque getExcludeFromNav, re-indexe e veja o resultado. Listando as notícias com imagem
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" lang="en" metal:use-macro="here/main_template/macros/master" i18n:domain="plone"> <body metal:fill-slot="main"> <div tal:define="noticias python:context.portal_catalog(portal_type='News Item', verifica_img_noticia=True)"> <div tal:repeat="item noticias"> <h3 tal:content="item/Title">Titulo</h3> <img tal:attributes="src string:${item/getURL}/image_thumb"/> </div> </div> </body> </html>
Pronto agora teremos apenas as noticias com foto.
Só idéia boa!
Digamos que você queira mostrar todas as notícias e caso ela não tenha imagem você mostra a mensagem "Imagem Indisponível", bem você pensaria é simples basta fazer o código abaixo:
Isso não funciona!! TraversalError!! <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" lang="en" metal:use-macro="here/main_template/macros/master" i18n:domain="plone"> <body metal:fill-slot="main"> <h1>Listagem de Noticias</h1> <div tal:define="noticias python:context.portal_catalog(portal_type='News Item')"> <div tal:repeat="item noticias"> <h3 tal:content="item/Title">Titulo</h3> <tal:image tal:condition="item/verifica_img_noticia"> <img tal:attributes="src string:${item/getURL}/image_thumb"/> </tal:image> <tal:image tal:condition="not: item/verifica_img_noticia"> Mensagem Indisponível! </tal:image> </div> </div> </body> </html>É verdade pode testar isso não funciona, não sei ao certo por que mas quando você cria um novo índice no catálogo você não consegue chamalo a cada brain, mas calma não priemos cânico, pois existe uma solução e os créditos dela vão ao meu grande amigo Douglas Soares de Andrade <dsandrade@gmail.com>, se esse código também te salvar agradeça a ele, então é o seguinte faça isso:
Gambiarra da Boa! <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" lang="en" metal:use-macro="here/main_template/macros/master" i18n:domain="plone"> <body metal:fill-slot="main"> <h1>Listagem de Noticias</h1> <div tal:define="noticias python:context.portal_catalog(portal_type='News Item')"> <div tal:repeat="item noticias"> <h3 tal:content="item/Title">Titulo</h3> <tal:image tal:condition="python: context.portal_catalog.getIndexDataForRID(item.getRID()) ['verifica_img_noticia']"> <img tal:attributes="src string:${item/getURL}/image_thumb"/> </tal:image> <tal:image tal:condition="not: python: context.portal_catalog.getIndexDataForRID(item.getRID()) ['verifica_img_noticia']"> Sem Imagem </tal:image> </div> </div> </body> </html>
Legal né melhore isso criando um script python onde você passa o brain como parâmetro e ele verifica e retorna True ou False, fica como exercício de casa.
Legal mas por que será que o item/verifica_img_noticia, não funciona?
Cara isso são resultados das maldades utilizadas por baixo do catálogo, mas enfim!
Gostou deste artigo então comenta,
por favor se copiar mantenha os créditos.
Herson Rodrigues - hersonrodrigues@gmail.com