add portuguese docs

This commit is contained in:
mohrt
2003-12-23 15:53:39 +00:00
parent 5b255f9d1d
commit ae3b538314
11 changed files with 10544 additions and 0 deletions
+404
View File
@@ -0,0 +1,404 @@
<part id="appendixes"><!-- En Version: 1.12 -->
<title>Apêndices</title>
<chapter id="troubleshooting">
<title>Localização de Erros</title>
<para></para>
<sect1 id="smarty.php.errors">
<title>erros de Smarty/PHP </title>
<para>
O Smarty pode obter muitos erros tais como, atributos de tags perdidos ou nomes de variáveis
mal formadas. Se isto acontece, você verá
um erro como segue:
</para>
<example>
<title>Erros do Smarty</title>
<programlisting>
Warning: Smarty: [in index.tpl line 4]: syntax error: unknown tag - '%blah'
in /path/to/smarty/Smarty.class.php on line 1041
Fatal error: Smarty: [in index.tpl line 28]: syntax error: missing section name
in /path/to/smarty/Smarty.class.php on line 1041</programlisting>
</example>
<para>
O Smarty te mostra o nome do template, o número da linha e o erro.
Depois disso, o erro consiste do número da linha da classe Smarty em que o erro
ocorreu.
</para>
<para>
Há certos erros que o smarty não pode entender, tais como um um fechamento de tags errado.
Estes tipos de erros normalmente
termina na interpretação de erros do tempo de compilação do PHP.
</para>
<example>
<title>Erros de análise do PHP</title>
<programlisting>
Parse error: parse error in /path/to/smarty/templates_c/index.tpl.php on line 75</programlisting>
</example>
<para>
Quando você encontra um erro de análise de PHP, o número da linha do erro corresponderá ao
script PHP compilado, não o template em si. Normalmente você pode no template localizar o
erro de sintaxe. Aqui algumas coisas para você procurar:
falta de fechamento de tags para {if}{/if} ou
{section}{/section}, ou sintaxe da lógica dentro de uma tag {if}.
Se você não encontra o erro, você pode ter
que abrir o arquivo PHP compilado e ir até o numero da linha exibido, no local onde o erro correspondente
está no template.
</para>
</sect1>
</chapter>
<chapter id="tips">
<title>Dicas &amp; Truques</title>
<para>
</para>
<sect1 id="tips.blank.var.handling">
<title>Manipulação de Variável Vazia</title>
<para>
Quando você quer algumas vezes imprimir um valor que você definir para uma variável vazia
ao invés de imprimir nada, tal como imprimindo "&amp;nbsp;" a fim de que plano de fundo de tabelas
funcionem corretamente. Muitos usariam uma instrução {if} para manipular isto, mas há um
macete com o Smarty, usando o modificador de variável
<emphasis>default</emphasis>.
</para>
<example>
<title>Imprimindo &amp;nbsp; quando uma variável está vazia</title>
<programlisting>
{* A forma mais longa *}
{if $title eq ""}
&amp;nbsp;
{else}
{$title}
{/if}
{* A forma mais simples *}
{$title|default:"&amp;nbsp;"}</programlisting>
</example>
</sect1>
<sect1 id="tips.default.var.handling">
<title>Manipulação do valor padrão de Variável</title>
<para>
Se uma variável é usada freqüentemente em seus templates, aplicando o modificador
default toda vez que ela é mencionado pode evitar um bit desagradável. Você pode remediar isto
pela atribuição de um valor padrão para a variável com a função
<link linkend="language.function.assign">assign</link>.
</para>
<example>
<title>Atribuindo o valor padrão para uma variável de template</title>
<programlisting>
{* faça isto em algum lugar no topo de seu template *}
{assign var="titulo" value=$titulo|default:"sem título"}
{* Se o $titulo estava vazio, ele agora contém o valor "sem titulo" quando você exibí-lo *}
{$title}</programlisting>
</example>
</sect1>
<sect1 id="tips.passing.vars">
<title>Passando a variável titulo para o template de cabeçalho</title>
<para>
Quando a maioria de seus templates usam os mesmos cabeçalhos e mesmos rodapés, é
comum dividi-los um em cada template e então incluí-los. Mas o que fazer se o
cabeçalho precisa ter um titulo diferente, dependendo de que página ele está vindo?
Você pode passar o titulo para o
cabeçalho quando ele é incluído.
</para>
<example>
<title>Passando a variável titulo para o template de cabeçalho</title>
<programlisting>
mainpage.tpl
------------
{include file="header.tpl" titulo="Página Principal"}
{* O corpo do template vem aqui *}
{include file="footer.tpl"}
archives.tpl
------------
{config_load file="archive_page.conf"}
{include file="header.tpl" titulo=#archivePageTitle#}
{* O corpo do template vem aqui *}
{include file="footer.tpl"}
header.tpl
----------
&lt;HTML&gt;
&lt;HEAD&gt;
&lt;TITLE&gt;{$titulo|default:"BC News"}&lt;/TITLE&gt;
&lt;/HEAD&gt;
&lt;BODY&gt;
footer.tpl
----------
&lt;/BODY&gt;
&lt;/HTML&gt;</programlisting>
</example>
<para>
Quando a página principal é atraída, o título da "Página Principal" é passado para o template
header.tpl, e será subseqüencialmente usado com o título. Quando a página de arquivamento é atraída,
o título será "Archives". Note no exemplo de archive, nós estamos usando uma variável do arquivo
archives_page.conf ao invés de uma variável codificada rígida.
Também note que "BC news" é exibida se
a variável $titulo não está definida,
usando o modificador de variável <emphasis>default</emphasis>.
</para>
</sect1>
<sect1 id="tips.dates">
<title>Datas</title>
<para>
Como uma regra básica, sempre passe datas para o smarty como timestamps. Isto permite ao
desenhista de template utilizar <link linkend="language.modifier.date.format">date_format</link>
para controle completo sobre a formatação de data,
e também facilita a comparação de datas se
necessário.
</para>
<para>
NOTA: No Smarty 1.4.0, você pode passar datas para o Smarty como timestamps unix,
mysql, ou qualquer outra data interpretável por strtotime().
</para>
<example>
<title>Usando date_format</title>
<programlisting>
{$startDate|date_format}
SAÍDA:
Jan 4, 2001
{$startDate|date_format:"%Y/%m/%d"}
SAÍDA:
2001/01/04
{if $date1 &lt; $date2}
...
{/if}</programlisting>
</example>
<para>
Quando usando {html_select_date} em um template, o programador normalmente vai querer converter
a saída de um formulário de volta para o formato de timestamp. Aqui está uma função para ajudar
com isso.
</para>
<example>
<title>Convertendo elementos em forma de data de volta para um timestamp</title>
<programlisting>
// isto assume que a forma de seus elementos são nomeadas como
// startDate_Day, startDate_Month, startDate_Year
$startDate = makeTimeStamp($startDate_Year,$startDate_Month,$startDate_Day);
function makeTimeStamp($year="",$month="",$day="")
{
if(empty($year))
$year = strftime("%Y");
if(empty($month))
$month = strftime("%m");
if(empty($day))
$day = strftime("%d");
return mktime(0,0,0,$month,$day,$year);
}</programlisting>
</example>
</sect1>
<sect1 id="tips.wap">
<title>WAP/WML</title>
<para>
Os templates WAP/WML requerem um cabeçalho de Content-Type de PHP para ser passado junto com
template. A forma mais fácil de fazer isto seria escrever uma função customizada que imprime
o cabeçalho. Se você está usando sistema de caching, esse não funcionará, então nós faremos isso
usando a tag de insert (lembre que tags de insert não são "cached!") Certifique-se que não há saída
para o navegador antes do template,
senão o cabeçalho irá falhar.
</para>
<example>
<title>Usando insert para escrever um cabeçalho WML Content-Type</title>
<programlisting>
// esteja certo que o apache está configurado para as extensões .wml !
// ponha esta função em algum lugar de sua aplicação, ou em Smarty.addons.php
function insert_header() {
// esta função espera o argumento $content
extract(func_get_arg(0));
if(empty($content))
return;
header($content);
return;
}
// seu template Smarty _deve_ começar com a insert tag, olha o exemplo:
{insert name=header content="Content-Type: text/vnd.wap.wml"}
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"&gt;
&lt;!-- begin new wml deck --&gt;
&lt;wml&gt;
&lt;!-- begin first card --&gt;
&lt;card&gt;
&lt;do type="accept"&gt;
&lt;go href="#two"/&gt;
&lt;/do&gt;
&lt;p&gt;
Bem-vindo ao WAP com Smarty!
Pressione OK para continuar...
&lt;/p&gt;
&lt;/card&gt;
&lt;!-- begin second card --&gt;
&lt;card id="two"&gt;
&lt;p&gt;
Bem fácil isso, não é?
&lt;/p&gt;
&lt;/card&gt;
&lt;/wml&gt;</programlisting>
</example>
</sect1>
<sect1 id="tips.componentized.templates">
<title>Templates componentizados</title>
<para>
Esta dica é um pouco de hack, mas ainda é uma idéia limpa.
Use-a por seu próprio risco. ;-)
</para>
<para>
Tradicionalmente, programar templates em suas aplicações segue esta forma:
Primeiro, você acumula suas variáveis dentro de sua aplicação PHP, (talvez com requisições
de banco de dados.) Então, você instancia seu objeto Smarty, atribui valores às variáveis
e exibe o template. Por exemplo nós temos um registrador de estoque em nosso template.
Nós coletaríamos os dados estocagem em nossa aplicação, então damos valor a estas variáveis
no template e o exibimos. Agora isso seria legal
se você adicionasse este registrador de
armazenamento (stock ticker) para qualquer aplicação simplesmente incluindo o template, e sem
se preocupar com a busca de dados mais a frente?
</para>
<para>
Você pode embutir o PHP dentro de seus templates com as tags {php}{/php}.
Com isto, você pode configurar templates independentes, tendo a sua própria
estrutura de dados para dar valor às suas próprias variáveis. Com a lógica embutida
dessa forma, você pode manter a lógica do template &amp; junto. Desta maneira não é
importante de onde o fonte do
template está vindo, ele está sempre junto como um componente.
</para>
<example>
<title>Template componentizado</title>
<programlisting>
{* Smarty *}
{php}
// configurar nossa função para buscar dados armazenados
function fetch_ticker($symbol,&amp;$ticker_name,&amp;$ticker_price) {
// ponha a lógica aqui que procura $ticker_name
// e $ticker_price de algum recurso
}
// chama a função
fetch_ticker("YHOO",$ticker_name,$ticker_price);
// passando valores às variáveis de template
$this->assign("ticker_name",$ticker_name);
$this->assign("ticker_price",$ticker_price);
{/php}
Nome do Estoque: {$ticker_name} Preço do Estoque: {$ticker_price}</programlisting>
</example>
<para>
No Smarty 1.5.0, há até uma forma mais limpa. Você pode incluir o php em seus templates com
a tag {include_php ...}.
Desta forma você pode manter a lógica do PHP separada da lógica do
template. Veja a função <link linkend="language.function.include.php">include_php</link> para
mais informação.
</para>
<example>
<title>Template componentizado com include_php</title>
<programlisting>
load_ticker.php
---------------
&lt;?php
// configura nossa função para buscar os dados armazenados
function fetch_ticker($symbol,&amp;$ticker_name,&amp;$ticker_price) {
// ponha aqui a lógica que procura $ticker_name
// e $ticker_price de algum recurso
}
// chama a função
fetch_ticker("YHOO",$ticker_name,$ticker_price);
// passar valores para as variáveis de template
$this->assign("ticker_name",$ticker_name);
$this->assign("ticker_price",$ticker_price);
?&gt;
index.tpl
---------
{* Smarty *}
{include_php file="load_ticker.php"}
Nome do Estoque: {$ticker_name} Preço do Estoque: {$ticker_price}</programlisting>
</example>
</sect1>
<sect1 id="tips.obfuscating.email">
<title>Ofuscando endereços de E-mail</title>
<para>
Você deseja saber como seu endereço de E-mail consegue entrar em tantas listas de email de spam?
A única forma de spammers coletar endereços de E-mail é de páginas da web. Para ajudar a combater
este problema, você pode fazer o seu endereço de E-mail aparecer em javascript misturado no
código HTML, mesmo assim ele aparecerá e funcionará corretamente no navegador. Isto é feito com
o plugin mailto.
</para>
<example>
<title>Exemplo de ofuscamento de um Endereço de E-mail</title>
<programlisting>
index.tpl
---------
envia inquisição para
{mailto address=$EmailAddress encode="javascript" subject="Olá"}
</programlisting>
</example>
<note>
<title>Nota técnica</title>
<para>
Este método não é 100% a prova de falha. Um spammer poderia criar um programa
para coletar o e-mail e para decodificar estes valores, mas não é muito comum.
</para>
</note>
</sect1>
</chapter>
<chapter id="resources">
<title>Recursos</title>
<para>
A homepage do Smarty está localizada em http://smarty.php.net/.
Você pode entrar na lista de email enviando um e-mail para
smarty-general-subscribe@lists.php.net. Um arquivo da lista de e-mail pode ser
visto em http://marc.theaimsgroup.com/?l=smarty&amp;r=1&amp;w=2
</para>
</chapter>
<chapter id="bugs">
<title>BUGS</title>
<para>
Verifique o arquivo de BUGS que vêm com a última distribuição do Smarty, ou
verifique o website.
</para>
</chapter>
</part>
+46
View File
@@ -0,0 +1,46 @@
;; -*- Scheme -*-
;;
;; $Id$
;;
;; This file contains stylesheet customization common to the HTML
;; and print versions.
;;
;; Stylesheets Localization
(define %default-language% "pt_BR")
(define %use-id-as-filename% #t)
(define %gentext-nav-tblwidth% "100%")
(define %refentry-function% #t)
(define %refentry-generate-name% #f)
(define %funcsynopsis-style% 'ansi)
(define ($legalnotice-link-file$ legalnotice)
(string-append "copyright" %html-ext%))
(define %generate-legalnotice-link% #t)
(define %footnotes-at-end% #t)
(define %force-chapter-toc% #t)
(define newline "\U-000D")
(define %number-programlisting-lines% #f)
(define %linenumber-mod% 1)
(define %shade-verbatim% #t)
(define ($generate-book-lot-list$)
;; REFENTRY generate-book-lot-list
;; PURP Which Lists of Titles should be produced for Books?
;; DESC
;; This parameter should be a list (possibly empty) of the elements
;; for which Lists of Titles should be produced for each 'Book'.
;;
;; It is meaningless to put elements that do not have titles in this
;; list. If elements with optional titles are placed in this list, only
;; the instances of those elements that do have titles will appear in
;; the LOT.
;;
;; /DESC
;; AUTHOR N/A
;; /REFENTRY
(list (normalize "table")))
(define (php-code code)
(make processing-instruction
data: (string-append "php " code "?")))
File diff suppressed because it is too large Load Diff
+398
View File
@@ -0,0 +1,398 @@
<part id="getting.started"><!-- En Version: 1.24 -->
<title>Iniciando</title>
<chapter id="what.is.smarty">
<title>O que é o Smarty?</title>
<para>
Smarty uma ferramenta de template para PHP. Mais especificamente, ela facilita
uma forma controlável de separar a aplicação lógica e o conteúdo de sua apresentação.
Isto é melhor descrito em uma situação onde o programador da aplicação e o designer
do template executam diferentes funções, ou na maioria dos casos não são a mesma pessoa.
Por exemplo, digamos que você está criando uma página que está mostrando um artigo de
jornal. O autor, a manchete, a conclusão e o corpo do artigo são elementos de conteúdo, eles
não contém informação sobre como eles serão apresentados. Eles são passados para o Smarty
pela aplicação, então o designer de template edita o template e usa uma combinação de tags
HTML e tags de template para formatar a apresentação destes elementos (tabelas HTML, cores
de planos de fundo, tamanhos da fonte, folhas de estilos, etc.).
Quando o programador necessita
mudar a forma em que o conteúdo do artigo é
devolvido (uma mudança da lógica da aplicação.) Esta
mudança não afeta o designer do template, o conteúdo ainda chegará no template exatamente da
mesma forma. De modo semelhante, se o designer de template quer redesenhar completamente
o template, isto não requer mudanças na lógica da aplicação. Então o programador pode fazer
mudanças na lógica da aplicação sem precisar reestruturar os templates,
e o designer de template
pode fazer mudanças no template sem quebrar a lógica da aplicação.
</para>
<para>
Agora um resumo sobre o que o Smarty faz e NÃO faz. O Smarty não tenta separar completamente
a lógica dos templates. Não há problema com a lógica em seus templates sob a condição de que
esta lógica seja estritamente para apresentação. Uma palavra de aviso: mantenha a lógica
fora dos templates, e a lógica da apresentação fora da aplicação. Isto definitivamente
manterá as coisas mais manipuláveis
e escaláveis para o futuro próximo.
</para>
<para>
Um dos aspectos únicos sobre o Smarty é a compilação do template. Isto significa que o
Smarty lê os arquivos de template e cria scripts PHP a partir deles. Uma vez criados, eles
são executados. Então não há interpretação de arquivo de
template custosa para cada pedido, e
cada template pode levar total vantagem de soluções de cache de compiladores PHP tais como
Zend Accelerator (http://www.zend.com) ou PHP Accelerator
(http://www.php-accelerator.co.uk).
</para>
<para>
Algumas das características do Smarty:
</para>
<itemizedlist>
<listitem><para>Ele é extremamente rápido.</para></listitem>
<listitem><para>Ele é eficiente visto que
o interpretador de PHP faz o trabalho mais chato.</para></listitem>
<listitem><para>Sem elevadas interpretações de template, apenas compila uma vez.</para></listitem>
<listitem><para>Ele está atento para só recompilar os arquivos de template que
foram mudados.</para></listitem>
<listitem><para>Você pode criar <link linkend="language.custom.functions">funções customizadas
</link> e <link linkend="language.modifiers">modificadores de variáveis
</link> customizados, de modo que a linguagem de template é extremamente extensível.</para></listitem>
<listitem><para>Sintaxe de tag delimitadora de template configurável, assim você pode usar
{}, {{}}, &lt;!--{}--&gt;, etc.</para></listitem>
<listitem><para>Os construtoress if/elseif/else/endif são passados para o interpretador de PHP,
assim a sintaxe de expressão {if ...} pode ser tanto simples quanto complexa da forma que você
queira.</para></listitem>
<listitem><para>Aninhamento ilimitado de sections, ifs, etc. permitidos.</para></listitem>
<listitem><para>É possível embutir o código PHP diretamente em seus arquivos de template,
apesar de que isto pode não ser necessário (não recomendado)
visto que a ferramenta é tão customizável.</para></listitem>
<listitem><para>Suporte de caching embutido</para></listitem>
<listitem><para>Fontes de template arbitrárias</para></listitem>
<listitem><para>Funções de manipulação de cache customizadas</para></listitem>
<listitem><para>Arquitetura de Plugin</para></listitem>
</itemizedlist>
</chapter>
<chapter id="installation">
<title>Instalação</title>
<sect1 id="installation.requirements">
<title>Requerimentos</title>
<para>
Smarty requer um servidor web rodando o PHP 4.0.6 superior.
</para>
</sect1>
<sect1 id="installing.smarty.basic">
<title>Instalação Básica</title>
<para>
Instale os arquivos da biblioteca do Smarty que estão no diretório /libs/ da
distribuição. Estes são os arquivos PHP que você NÃO EDITARIA. Eles são comuns
a todas as aplicações e eles só são atualizados quando você atualiza para uma nova
versão do Smarty.
</para>
<example>
<title>Arquivos da biblioteca do Smarty</title>
<screen>
Smarty.class.php
Smarty_Compiler.class.php
Config_File.class.php
debug.tpl
/core/*.php (todos eles)
/plugins/*.php (todos eles)</screen>
</example>
<para>
O Smarty utiliza uma constante do PHP chamada <link
linkend="constant.smarty.dir">SMARTY_DIR</link> que é o caminho para diretório da
biblioteca do Smarty. Basicamente, se sua aplicação pode encontrar o arquivo
<emphasis>Smarty.class.php</emphasis>, você não precisa definir o
SMARTY_DIR, Smarty encontrará-lo. Então, se <emphasis>Smarty.class.php</emphasis> não está
em seu include_path, ou você não fornece um caminho absoluto para ele em sua aplicação, então
você deve definir o SMARTY_DIR manualmente.
SMARTY_DIR <emphasis>deve</emphasis> incluir uma
barra de seguimento.
</para>
<para>
Aqui está um exemplo de como você cria uma instância do Smarty em seus scripts PHP:
</para>
<example>
<title>Cria uma instância Smarty do Smarty</title>
<screen>
require('Smarty.class.php');
$smarty = new Smarty;</screen>
</example>
<para>
Tente rodar o script acima. Se você obtiver um erro dizendo que o arquivo
<emphasis>Smarty.class.php</emphasis> file could not be found, você tem que fazer uma
das coisas a seguir:
</para>
<example>
<title>Fornecer um caminho absoluto para o arquivo da biblioteca</title>
<screen>
require('/usr/local/lib/php/Smarty/Smarty.class.php');
$smarty = new Smarty;</screen>
</example>
<example>
<title>Adicionar o diretório da biblioteca para o include_path do PHP</title>
<screen>
// Edite o seu arquivo php.ini, adicione o diretório da biblioteca do Smarty
// para o include_path e reinicie o servidor web.
// Então o código a seguir funcionaria:
require('Smarty.class.php');
$smarty = new Smarty;</screen>
</example>
<example>
<title>Defina a constante SMARTY_DIR manualmente</title>
<screen>
define('SMARTY_DIR','/usr/local/lib/php/Smarty/');
require(SMARTY_DIR.'Smarty.class.php');
$smarty = new Smarty;</screen>
</example>
<para>
Agora que os arquivos da biblioteca estão no lugar, chegou a hora de configurar os
diretórios do Smarty para a sua aplicação. O Smarty requer quatro diretórios que são
(por definição) chamados de <emphasis>templates</emphasis>,
<emphasis>templates_c</emphasis>, <emphasis>configs</emphasis> e
<emphasis>cache</emphasis>. Cada um destes são definíveis pelas propriedades da classe do Smarty
<emphasis>$template_dir</emphasis>,
<emphasis>$compile_dir</emphasis>, <emphasis>$config_dir</emphasis>, e
<emphasis>$cache_dir</emphasis> respectivamente. É altamente recomendado que você configure
um grupo separado destes diretórios
para cada aplicação que utilizará o Smarty.
</para>
<para>
Certifique-se que você sabe a localização do document root do seu servidor web. Em nosso exemplo,
o document root é "/web/www.mydomain.com/docs/". Os diretórios do Smarty
só são acessados pela biblioteca do Smarty e nunca acessados diretamente pelo navegador. Então para
evitar qualquer preocupação com segurança,
é recomendado colocar estes diretórios
<emphasis>fora</emphasis> do document root.
</para>
<para>
Para o nosso exemplo de instalação, nós estaremos configurando o ambiente do Smarty
para uma aplicação de livro de visitas. Nós escolhemos uma aplicação só para o propósito
de uma convenção de nomeação de diretório. Você pode usar o mesmo ambiente para qualquer
aplicação, apenas substitua "guestbook" com o nome de sua aplicação. Nós colocaremos nossos
diretórios do Smarty dentro de
"/web/www.mydomain.com/smarty/guestbook/".
</para>
<para>
Você precisará pelo menos de um arquivo dentro de seu document root, e que seja acessado pelo
navegador. Nós chamamos nosso
script de "index.php", e o colocamos em um subdiretório dentro
do document root chamado "/guestbook/".
</para>
<note>
<title>Nota Técnica</title>
<para>
É conveniente configurar o servidor de forma que "index.php" possa ser identificado
como o índice de diretório padrão, desta forma se você acessa
"http://www.mydomain.com/guestbook/", o script index.php será executado
sem "index.php" na URL. No Apache você pode definir isto adicionando
"index.php" no final de sua configuração
DirectoryIndex (separe cada entrada com um espaço.)
</para>
</note>
<para>
Vamos dar uma olhada na estrutura de arquivos até agora:
</para>
<example>
<title>Exemple de estrutura de arquivo</title>
<screen>
/usr/local/lib/php/Smarty/Smarty.class.php
/usr/local/lib/php/Smarty/Smarty_Compiler.class.php
/usr/local/lib/php/Smarty/Config_File.class.php
/usr/local/lib/php/Smarty/debug.tpl
/usr/local/lib/php/Smarty/core/*.php
/usr/local/lib/php/Smarty/plugins/*.php
/web/www.mydomain.com/smarty/guestbook/templates/
/web/www.mydomain.com/smarty/guestbook/templates_c/
/web/www.mydomain.com/smarty/guestbook/configs/
/web/www.mydomain.com/smarty/guestbook/cache/
/web/www.mydomain.com/docs/guestbook/index.php</screen>
</example>
<para>
O Smarty precisará escrever para o <emphasis>$compile_dir</emphasis> e
<emphasis>$cache_dir</emphasis>, então garanta que o usuário do servidor web possa
escrever neles. Este é geralmente o usuário "nobody" e o grupo "nobody" (ninguém). Para
SO com X usuários, o usuário padrão é "www" e o grupo "www". Se você está usando Apache, você
pode olhar em seu arquivo httpd.conf (normalmente em "/usr/local/apache/conf/") para ver
qual o usuário e grupo estão sendo usados.
</para>
<example>
<title>Configurando permissões de arquivos</title>
<screen>
chown nobody:nobody /web/www.mydomain.com/smarty/guestbook/templates_c/
chmod 770 /web/www.mydomain.com/smarty/guestbook/templates_c/
chown nobody:nobody /web/www.mydomain.com/smarty/guestbook/cache/
chmod 770 /web/www.mydomain.com/smarty/guestbook/cache/</screen>
</example>
<note>
<title>Nota Técnica</title>
<para>
chmod 770 será a segurança correta suficientemente restrita, só permite ao usuário "nobody" e
o grupo "nobody" acesso de leitura/escrita aos diretórios. Se você gostaria de abrir o acesso de leitura
para qualquer um (na maioria das vezes para sua própria conveniência de querer ver estes
arquivos), você pode usar o 775 ao invés do 770.
</para>
</note>
<para>
Nós precisamos criar o arquivoindex.tpl que o Smarty vai ler. Ele estará localizado em seu
$template_dir.
</para>
<example>
<title>Editando /web/www.mydomain.com/smarty/guestbook/templates/index.tpl</title>
<screen>
{* Smarty *}
Olá, {$nome}!</screen>
</example>
<note>
<title>Nota Técnica</title>
<para>
{* Smarty *} é um comentário de template. Ele não é exigido, mas é uma prática boa
iniciar todos os seus arquivos de template com este com este comentário. Isto faz com
que o arquivo seja reconhecido sem levar em consideração a sua extensão. Por exemplo,
editores de texto poderiam reconhecer
o arquivo e habilitar iluminação de sintaxe especial.
</para>
</note>
<para>
Agora vamos editar index.php. Nós criaremos uma instância do Smarty, daremos valor às variáveis
de template e mostraremos o arquivo index.tpl. Em nosso ambiente de exemplo,
"/usr/local/lib/php/Smarty" é o nosso include_path. Certifique-se de ter feito o mesmo, ou use
caminhos absolutos.
</para>
<example>
<title>Editando /web/www.mydomain.com/docs/guestbook/index.php</title>
<screen>
// ler a biblioteca do Smarty
require('Smarty.class.php');
$smarty = new Smarty;
$smarty->template_dir = '/web/www.mydomain.com/smarty/guestbook/templates/';
$smarty->compile_dir = '/web/www.mydomain.com/smarty/guestbook/templates_c/';
$smarty->config_dir = '/web/www.mydomain.com/smarty/guestbook/configs/';
$smarty->cache_dir = '/web/www.mydomain.com/smarty/guestbook/cache/';
$smarty->assign('nome','Taniel');
$smarty->display('index.tpl');</screen>
</example>
<note>
<title>Nota Técnica</title>
<para>
Em nosso exemplo, nós estamos configurando caminhos absolutos para todos os diretórios
do Smarty. Se '/web/www.mydomain.com/smarty/guestbook/' está dentro de seu include_path
do PHP, então estas configurações não são necessárias. Entretanto, isto é mais eficiente
e (a experiência mostra) tem menos tendência a erros em relação à definição de caminhos
absolutos. Isto garante que o
Smarty está pegando arquivos do diretório que você deseja.
</para>
</note>
<para>
Agora lê o arquivo index.php de seu navegador.
Você veria "Olá, Taniel!"
</para>
<para>
Você completou a configuração básica para o Smarty!
</para>
</sect1>
<sect1 id="installing.smarty.extended">
<title>Expandindo a configuração</title>
<para>
Esta é uma continuação da <link
linkend="installing.smarty.basic">instalação básica</link>,
por favor leia ela primeiro!
</para>
<para>
Uma forma um pouco mais flexível de configurar o Smarty é expandir a classe e inicializar seu ambiente de
Smarty. Então, ao invés de configurar caminhos de diretórios repetidamente, preencher as mesmas variáveis,
etc., nós podemos fazer isso para facilitar. Vamos criar um novo diretório "/php/includes/guestbook/" e criar um
novo arquivo chamado "setup.php". Em nosso ambiente de exemplo, "/php/includes" está em nosso
include_path. Certifique-se de que você
também definiu isto, ou use caminhos de arquivos absolutos.
</para>
<example>
<title>Editando /php/includes/guestbook/setup.php</title>
<screen>
// lê a biblioteca do Smarty
require('Smarty.class.php');
// O arquivo setup.php é uma boa forma para ler
// arquivos de bibliotecas da aplicação exigida, e você pode fazer
// isso corretamente aqui. Um exemplo:
// require('guestbook/guestbook.lib.php');
class Smarty_GuestBook extends Smarty {
function Smarty_GuestBook() {
// Construtor da Classe. Estes automaticamente são definidos a cada nova instância.
$this->Smarty();
$this->template_dir = '/web/www.mydomain.com/smarty/guestbook/templates/';
$this->compile_dir = '/web/www.mydomain.com/smarty/guestbook/templates_c/';
$this->config_dir = '/web/www.mydomain.com/smarty/guestbook/configs/';
$this->cache_dir = '/web/www.mydomain.com/smarty/guestbook/cache/';
$this->caching = true;
$this->assign('app_name','Guest Book');
}
}</screen>
</example>
<para>
Agora vamos alterar o arquivo index.php para usar o setup.php:
</para>
<example>
<title>Editando /web/www.mydomain.com/docs/guestbook/index.php</title>
<screen>
require('guestbook/setup.php');
$smarty = new Smarty_GuestBook;
$smarty->assign('nome','Taniel');
$smarty->display('index.tpl');</screen>
</example>
<para>
Agora você ver que é completamente simples criar uma instância do Smarty, apenas use
Smarty_GuestBook que automaticamente inicializa tudo para a nossa aplicação.
</para>
</sect1>
</chapter>
</part>
+382
View File
@@ -0,0 +1,382 @@
;; -*- Scheme -*-
;;
;; $Id$
;;
;; Returns the depth of the auto-generated TOC (table of contents) that
;; should be made at the nd-level
(define (toc-depth nd)
(if (string=? (gi nd) (normalize "book"))
3 ; the depth of the top-level TOC
1 ; the depth of all other TOCs
))
(element (funcdef function)
($bold-seq$
(make sequence
(process-children)
)
)
)
(define (is-true-optional nl)
(and (equal? (gi (parent nl)) (normalize "parameter"))
(equal? 0 (string-length (strip (data (preced nl)))))
(equal? 0 (string-length (strip (data (follow nl)))))
)
)
(define (has-true-optional nl)
(is-true-optional
(node-list-first-element
(select-elements
(descendants nl)
(normalize "optional"))
)
)
)
(define (count-true-optionals nl)
(let loop
((result 0)
(nl (select-elements (descendants nl) (normalize "optional")))
)
(if(node-list-empty? nl)
result
(if(is-true-optional(node-list-first nl))
(loop (+ result 1) (node-list-rest nl))
(loop result (node-list-rest nl))
)
)
)
)
;; there are two different kinds of optionals
;; optional parameters and optional parameter parts
;; an optional parameter is identified by an optional tag
;; with a parameter tag as its parent
;; and only whitespace between them
(element optional
;;check for true optional parameter
(if (is-true-optional (current-node))
;; yes - handle '[...]' in paramdef
(process-children-trim)
;; no - do '[...]' output
(make sequence
(literal %arg-choice-opt-open-str%)
(process-children-trim)
(literal %arg-choice-opt-close-str%)
)
)
)
;; now this is going to be tricky
(element paramdef
(make sequence
;; special treatment for first parameter in funcsynopsis
(if (equal? (child-number (current-node)) 1)
;; is first ?
(make sequence
;; start parameter list
(literal "(")
;; is optional ?
( if (has-true-optional (current-node))
(literal %arg-choice-opt-open-str%)
(empty-sosofo)
)
)
;; not first
(empty-sosofo)
)
;;
(process-children-trim)
;; special treatment for last parameter
(if (equal? (gi (ifollow (current-node))) (normalize "paramdef"))
;; more parameters will follow
(make sequence
;; next is optional ?
( if (has-true-optional (ifollow (current-node)))
;; optional
(make sequence
(literal " ")
(literal %arg-choice-opt-open-str%)
)
;; not optional
(empty-sosofo)
)
(literal ", " )
)
;; last parameter
(make sequence
(literal
(let loop ((result "")(count (count-true-optionals (parent (current-node)))))
(if (<= count 0)
result
(loop (string-append result %arg-choice-opt-close-str%)(- count 1))
)
)
)
( literal ")" )
)
)
)
)
(element function
(let* ((function-name (data (current-node)))
(linkend
(string-append
"function."
(string-replace
(string-replace function-name "_" "-")
"::" ".")))
(target (element-with-id linkend))
(parent-gi (gi (parent))))
(cond
;; function names should be plain in FUNCDEF
((equal? parent-gi "funcdef")
(process-children))
;; if a valid ID for the target function is not found, or if the
;; FUNCTION tag is within the definition of the same function,
;; make it bold, add (), but don't make a link
((or (node-list-empty? target)
(equal? (case-fold-down
(data (node-list-first
(select-elements
(node-list-first
(children
(select-elements
(children
(ancestor-member (parent) (list "refentry")))
"refnamediv")))
"refname"))))
function-name))
($bold-seq$
(make sequence
(process-children)
(literal "()"))))
;; else make a link to the function and add ()
(else
(make element gi: "A"
attributes: (list
(list "HREF" (href-to target)))
($bold-seq$
(make sequence
(process-children)
(literal
)
(literal "()"))))))))
(element command
(let* ((command-name (data (current-node)))
(linkend
(string-append
"language.function."
(string-replace
(string-replace command-name "_" ".")
"::" ".")))
(target (element-with-id linkend))
(parent-gi (gi (parent))))
(cond
;; function names should be plain in FUNCDEF
((equal? parent-gi "funcdef")
(process-children))
;; if a valid ID for the target function is not found, or if the
;; FUNCTION tag is within the definition of the same function,
;; make it bold, add (), but don't make a link
((or (node-list-empty? target)
(equal? (case-fold-down
(data (node-list-first
(select-elements
(node-list-first
(children
(select-elements
(children
(ancestor-member (parent) (list "refentry")))
"refnamediv")))
"refname"))))
command-name))
($bold-seq$
(make sequence
(literal "{")
(process-children)
(literal "}"))))
;; else make a link to the function and add ()
(else
(make element gi: "A"
attributes: (list
(list "HREF" (href-to target)))
($bold-seq$
(make sequence
(literal "{")
(process-children)
(literal "}"))))))))
(element classname
(let* ((class-name (data (current-node)))
(linkend
(string-append
"class."
(string-replace
(case-fold-down class-name) "_" "-")))
(target (element-with-id linkend))
(parent-gi (gi (parent))))
(cond
;; function names should be plain in SYNOPSIS
((equal? parent-gi "synopsis")
(process-children))
;; if a valid ID for the target class is not found, or if the
;; CLASSNAME tag is within the definition of the same class,
;; make it bold, but don't make a link
((or (node-list-empty? target)
(equal? (case-fold-down
(data (node-list-first
(select-elements
(node-list-first
(children
(select-elements
(children
(ancestor-member (parent) (list "refentry")))
"refnamediv")))
"refname"))))
class-name))
($bold-seq$
(process-children)))
;; else make a link to the function and add ()
(else
(make element gi: "A"
attributes: (list
(list "HREF" (href-to target)))
($bold-seq$
(process-children)))))))
(element constant
(let* ((constant-name (data (current-node)))
(linkend
(string-append "constant."
(case-fold-down
(string-replace constant-name "_" "-"))))
(target (element-with-id linkend))
(parent-gi (gi (parent))))
(cond
; ;; constant names should be plain in FUNCDEF
; ((equal? parent-gi "funcdef")
; (process-children))
;; if a valid ID for the target constant is not found, or if the
;; CONSTANT tag is within the definition of the same constant,
;; make it bold, add (), but don't make a link
((or (node-list-empty? target)
(equal? (case-fold-down
(data (node-list-first
(select-elements
(node-list-first
(children
(select-elements
(children
(ancestor-member (parent) (list "refentry")))
"refnamediv")))
"refname"))))
constant-name))
($bold-mono-seq$
(process-children)))
;; else make a link to the function and add ()
(else
(make element gi: "A"
attributes: (list
(list "HREF" (href-to target)))
($bold-mono-seq$
(process-children)))))))
(element example
(make sequence
(make element gi: "TABLE"
attributes: (list
(list "WIDTH" "100%")
(list "BORDER" "0")
(list "CELLPADDING" "0")
(list "CELLSPACING" "0")
(list "CLASS" "EXAMPLE"))
(make element gi: "TR"
(make element gi: "TD"
($formal-object$))))))
(element (paramdef parameter)
(make sequence
font-posture: 'italic
(process-children-trim)
)
)
(mode book-titlepage-recto-mode
(element authorgroup
(process-children))
(element author
(let ((author-name (author-string))
(author-affil (select-elements (children (current-node))
(normalize "affiliation"))))
(make sequence
(make element gi: "DIV"
attributes: (list (list "CLASS" (gi)))
(literal author-name))
(process-node-list author-affil))))
)
(define (chunk-element-list)
(list (normalize "preface")
(normalize "chapter")
(normalize "appendix")
(normalize "article")
(normalize "glossary")
(normalize "bibliography")
(normalize "index")
(normalize "colophon")
(normalize "setindex")
(normalize "reference")
(normalize "refentry")
(normalize "part")
(normalize "sect1")
(normalize "sect2")
(normalize "section")
(normalize "book") ;; just in case nothing else matches...
(normalize "set") ;; sets are definitely chunks...
))
(define ($section-body$)
(make element gi: "DIV"
attributes: (list (list "CLASS" (gi)))
($section-separator$)
($section-title$)
(if (or (not (node-list-empty? (select-elements (children (current-node))
(normalize "sect2"))))
(not (node-list-empty? (select-elements (children (current-node))
(normalize "sect3")))))
(build-toc (current-node) 1)
(empty-sosofo))
(process-children)))
+21
View File
@@ -0,0 +1,21 @@
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY docbook.dsl SYSTEM "/usr/share/sgml/docbook/dsssl-stylesheets/html/docbook.dsl" CDATA DSSSL>
<!ENTITY html-common.dsl SYSTEM "html-common.dsl">
<!ENTITY common.dsl SYSTEM "common.dsl">
]>
<style-sheet>
<style-specification id="docbook-smarty-html" use="docbook">
<style-specification-body>
(define %html-ext% ".html")
&html-common.dsl;
&common.dsl;
</style-specification-body>
</style-specification>
<external-specification id="docbook" document="docbook.dsl">
</style-sheet>
+45
View File
@@ -0,0 +1,45 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
<!ENTITY preface SYSTEM "preface.sgml">
<!ENTITY getting.started SYSTEM "getting-started.sgml">
<!ENTITY smarty.for.designers SYSTEM "designers.sgml">
<!ENTITY smarty.for.programmers SYSTEM "programmers.sgml">
<!ENTITY appendixes SYSTEM "appendixes.sgml">
]>
<book id="index">
<bookinfo id="bookinfo">
<title>Smarty - a ferramenta para compilar templates para PHP</title>
<authorgroup id="authors">
<author>
<firstname>Monte</firstname><surname>Ohrt &lt;monte@ispi.net&gt;</surname>
</author>
<author>
<firstname>Andrei</firstname><surname>Zmievski &lt;andrei@php.net&gt;</surname>
</author>
</authorgroup>
<authorgroup id="translators">
<author>
<firstname>Fernando</firstname><surname>Correa da Conceição &lt;fernandoc@php.net&gt;</surname>
</author>
<author>
<firstname>Marcelo</firstname><surname>Perreira Fonseca da Silva &lt;marcelo@php.net&gt;</surname>
</author>
<author>
<firstname>Taniel</firstname><surname>Franklin &lt;taniel@ig.com.br&gt;</surname>
</author>
<edition>Versão 2.0</edition>
<copyright>
<year>2001</year>
<year>2002</year>
<year>2003</year>
<holder>ispi of Lincoln, Inc.</holder>
</copyright>
</bookinfo>
&preface;
&getting.started;
&smarty.for.designers;
&smarty.for.programmers;
&appendixes;
</book>
+21
View File
@@ -0,0 +1,21 @@
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY docbook.dsl SYSTEM "/usr/share/sgml/docbook/dsssl-stylesheets/html/docbook.dsl" CDATA DSSSL>
<!ENTITY html-common.dsl SYSTEM "html-common.dsl">
<!ENTITY common.dsl SYSTEM "common.dsl">
]>
<style-sheet>
<style-specification id="docbook-smarty-html" use="docbook">
<style-specification-body>
(define %html-ext% ".php")
&html-common.dsl;
&common.dsl;
</style-specification-body>
</style-specification>
<external-specification id="docbook" document="docbook.dsl">
</style-sheet>
+69
View File
@@ -0,0 +1,69 @@
<preface id="preface"><!-- En Version: 1.1 -->
<title>Prefácio</title>
<para>
Esta é uma das dúvidas mais frenquentes na "mailing list" do PHP:
Como eu posso fazer PHP scripts independentes do layout ? Enquanto
PHP está contado como "HTML linguagem de blocos dinâmicos", após estar
escrevendo alguns projetos que misturavam PHP e HTML livremente alguém veio com a
idéia que a separação do form e conteúdo é uma boa prática [TM]. Além disso,
em muitas empresas os papéis de web designer e programador são separados.
Consequentemente, a procura por
uma solução de template continua.
</para>
<para>
Na minha própria empresa por exemplo, o desenvolvimento de uma aplicação
continua como segue: Após a documentação necessária estar pronta, o web designer
faz a maquete da interface e entrega isso ao programador. O programador implementa
as regras de negócio no PHP e usa a maquete para criar o "esqueleto" do template.
O projeto está então nas mãos da pessoa responsável pelo layout HTML designer/web page
que produz o template para sua glória completa. O projeto deve ir e voltar
entre programação/HTML várias vezes. Desta maneira, é importante para ter
um bom suporte de template porque programadores não querem fazer nada
com HTML e não querem HTML designers fazendo besteiras no código PHP.
Designers precisam de suporte para arquivos de configuração, blocos dinâmicos e
outras interfaces usadas, mas eles não querem ocupar-se com
as complexidades da linguagem
de programação PHP.
</para>
<para>
Olhando para muitas soluções de template para PHP disponíveis atualmente,
a maioria destes disponibiliza uma forma rudimentar de substituição de variáveis
dentro de templates e fazem um form limitado de blocos dinâmicos de funcionalidades.
Mas minhas necessidades próprias requisitam um pouco mais do que isso.
Nós não queremos programadores mexendo com layout HTML em tudo, mas isso foi quase inevitável.
Por exemplo, se um designer quiser cores no background alternando-se em blocos dinâmicos,
isso tem que ser feito pelo programador antecipadamente. Nós também
precisamos que designers estejam habilitados a usar seus próprios arquivos de configuração,
e colocar variáveis deles dentro dos templates. A lista continua.
</para>
<para>
Nós iniciamos escrevendo por acaso um template engine por volta de 1999.
Após o término, nós começamos a trabalhar num template engine
escrito em C que esperançosamente foi aceito para ser incluso com PHP.
Nós não somente encontramos algumas complicadas barreiras técnicas, mas
houve também calorosos debates sobre exatamente o que um template engine devia
e não devia fazer. Desta experiência, nós decidimos que o template
engine deveria ser escrito em PHP como uma classe, para qualquer um usar da mesma forma
como eles vêem. Então nós escrevemos um engine que o
<productname>SmartTemplate</productname> nunca veio a existir (note: essa
classe nunca foi enviada ao público). Ela foi uma classe que
fazia quase tudo que gostaríamos: substituição de variáveis regular, suporte à
inclusão de outros templates, integração com arquivos de configuração, código PHP
embutido, funcionalidade 'if' limitada e muito mais blocos dinâmicos robustos
que poderia ser aninhados muitas vezes. Tudo isso com expressões regulares
e o código produzido será melhor, como nós diremos,
impenetrável. Isso era também notoriamente lento em grandes aplicações para todos
as interpretações e expressões regulares trabalhando em cada requisição.
O maior problema do ponto de vista de um programador foi toda a
necessidade de trabalhar no processamento de scripts PHP e processamento
de blocos dinâmicos de templates. Como nós fazemos isso facilmente?
</para>
<para>
Então vem a visão do que ultimamente virou a Smarty. Nós sabemos quão rápido
é um código PHP sem o overhead da interpretação do template. Nós também sabemos
quão meticuloso e autoritária a linguagem PHP deve ser ao olhar de um designer,
e isso poderia ser mascarado com uma simples sintaxe de template.
Então o que acontece se nós combinarmos
estas duas forças? Desta maneira, Smarty nasceu...
</para>
</preface>
File diff suppressed because it is too large Load Diff