Helpers YATL

Considere o seguinte código em um ponto de vista:

[[=DIV('this', 'is', 'a', 'test', _id='123', _class='myclass')]]

ele é processado como:

<div id="123" class="myclass">thisisatest</div>

`` Div`` é uma classe auxiliar, ou seja, algo que pode ser usado para construir HTML programaticamente. Corresponde ao HTML `` <div> tag ``.

Argumentos posicionais são interpretados como objetos contidos entre as tags de abrir e fechar. argumentos nomeados que começam com um sublinhado são interpretados como atributos de tags HTML (sem o sublinhado). Alguns helpers também têm argumentos nomeados que não começam com sublinhado; estes argumentos são específicos do tag.

Em vez de um conjunto de argumentos sem nome, um helper também pode ter uma única lista ou tupla como seu conjunto de componentes usando a notação `` * `` e pode levar um único dicionário como seu conjunto de atributos usando o `` ** ` `, por exemplo:

[[
contents = ['this', 'is', 'a', 'test']
attributes = {'_id':'123', '_class':'myclass'}
=DIV(*contents, **attributes)
]]

(Produz a mesma saída que antes).

O seguinte conjunto de helpers:

`` A``, `` BEAUTIFY``, `` BODY``, `` CAT``, `` CODE``, `` div``, `` EM``, `` Form``, `` H1``, `` h2``, `` H3``, `` H4``, `` H5``, `` H6``, `` HEAD``, `` HTML``, `` I` , IMG`,` INPUT`,` label`,` LI`,` LINK`,` Meta`,` METATAG`,` OL`, `` OPTION``, `` PRE``, `` SELECT``, `` SPAN``, `` STRONG``, `` TABLE``, `` TAG``, `` TBODY``, `` TD``, `` TEXTAREA``, `` TH``, `` THEAD``, `` TR``, `` UL``, `` XML``, `` sanitize``, `` xmlescape` `

pode ser usado para construir expressões complexas que podem então ser serializado para XML. Por exemplo:

[[=DIV(B(I("hello ", "<world>")), _class="myclass")]]

é prestado:

<div class="myclass"><b><i>hello &lt;world&gt;</i></b></div>

Ajudantes também podem ser serializados em cordas, de forma equivalente, com a `` __str__`` e os `` métodos xml``:

>>> print str(DIV("hello world"))
<div>hello world</div>
>>> print DIV("hello world").xml()
<div>hello world</div>

O mecanismo de helpers em py4web é mais do que um sistema para gerar HTML sem concatenar strings. Ele fornece uma representação do lado do servidor do objecto do modelo de documento (DOM).

Componentes de helpers podem ser referenciados através de sua posição, e helpers agir como listas com relação aos seus componentes:

>>> a = DIV(SPAN('a', 'b'), 'c')
>>> print a
<div><span>ab</span>c</div>
>>> del a[1]
>>> a.append(B('x'))
>>> a[0][0] = 'y'
>>> print a
<div><span>yb</span><b>x</b></div>

Atributos de helpers pode ser referenciado pelo nome, e helpers agir como dicionários com relação aos seus atributos:

>>> a = DIV(SPAN('a', 'b'), 'c')
>>> a['_class'] = 's'
>>> a[0]['_class'] = 't'
>>> print a
<div class="s"><span class="t">ab</span>c</div>

Note, o conjunto completo de componentes podem ser acessados ​​através de uma lista de chamada `` a.components``, eo conjunto completo de atributos podem ser acessados ​​através de um dicionário chamado `` a.attributes``. Assim, `` a [i] `` é equivalente a `` a.components [i] `` `` quando i`` é um número inteiro, e um `` [s] `` é equivalente a `` a.attributes [s] `` `` quando s`` é uma cadeia de caracteres.

Note que atributos auxiliares são passados ​​como argumentos para o auxiliar. Em alguns casos, no entanto, nomes de atributos incluem caracteres especiais que não são permitidos em identificadores Python (por exemplo, hífens) e, portanto, não podem ser usados ​​como nomes de argumentos de palavra-chave. Por exemplo:

DIV('text', _data-role='collapsible')

não vai funcionar porque <quotechar> _data-papel <quotechar> inclui um hífen, que irá produzir um erro de sintaxe Python.

Nesses casos, você tem um par de opções. É possível utilizar a `` data`` argumento (desta vez sem um sublinhado) para passar um dicionário de atributos relacionados sem a sua hífen líder, e a saída terá as combinações desejadas, por exemplo

>>> print DIV('text', data={'role': 'collapsible'})
<div data-role="collapsible">text</div>

ou você pode em vez disso passar os atributos como um dicionário e fazer uso de `` ** notação `` argumentos de função do Python, que mapeia um dicionário de (key: value) pares em um conjunto de argumentos de palavra-chave:

>>> print DIV('text', **{'_data-role': 'collapsible'})
<div data-role="collapsible">text</div>

Note-se que as entradas mais elaboradas irá introduzir entidades de caracteres HTML, mas eles vão trabalhar, no entanto, por exemplo,

>>> print DIV('text', data={'options':'{"mode":"calbox", "useNewStyle":true}'})
<div data-options="{&quot;mode&quot;:&quot;calbox&quot;, &quot;useNewStyle&quot;:true}">text</div>

Você também pode criar dinamicamente tags especiais:

>>> print TAG['soap:Body']('whatever', **{'_xmlns:m':'http://www.example.org'})
<soap:Body xmlns:m="http://www.example.org">whatever</soap:Body>

`` XML``

`` XML`` é um objeto usado para encapsular texto que não deve ser escapado. O texto pode ou não conter XML válido. Por exemplo, poderia conter JavaScript.

O texto neste exemplo é escapado:

>>> print DIV("<b>hello</b>")
<div>&lt;b&gt;hello&lt;/b&gt;</div>

usando `` XML`` você pode impedir escapar:

>>> print DIV(XML("<b>hello</b>"))
<div><b>hello</b></div>

Às vezes você quer renderizar HTML armazenado em uma variável, mas o HTML pode conter tags inseguras como scripts:

>>> print XML('<script>alert("unsafe!")</script>')
<script>alert("unsafe!")</script>

Un-escapou de entrada executável como este (por exemplo, entrou no corpo de um comentário em um blog) não é seguro, porque pode ser usado para gerar ataques Cross Site Scripting (XSS) contra outros visitantes da página.

O py4web `` helper XML`` pode higienizar nosso texto para evitar injeções e escapar todas as tags exceto aqueles que você permitir explicitamente. Aqui está um exemplo:

>>> print XML('<script>alert("unsafe!")</script>', sanitize=True)
&lt;script&gt;alert(&quot;unsafe!&quot;)&lt;/script&gt;

Os `` construtores XML``, por padrão, considere o conteúdo de algumas tags e alguns de seus atributos de segurança. Você pode substituir os padrões usando os opcionais `` permitted_tags`` e `` allowed_attributes`` argumentos. Aqui estão os valores padrão dos argumentos opcionais do `` helper XML``.

XML(text, sanitize=False,
    permitted_tags=['a', 'b', 'blockquote', 'br/', 'i', 'li',
       'ol', 'ul', 'p', 'cite', 'code', 'pre', 'img/'],
    allowed_attributes={'a':['href', 'title'],
       'img':['src', 'alt'], 'blockquote':['type']})

Built-in helpers

`` A``

Este assistente é usado para construir ligações.

>>> print A('<click>', XML('<b>me</b>'),
            _href='http://www.py4web.com')
<a href='http://www.py4web.com'>&lt;click&gt;<b>me</b></a>

`` BODY``

Este assistente faz com que o corpo de uma página.

>>> print BODY('<hello>', XML('<b>world</b>'), _bgcolor='red')
<body bgcolor="red">&lt;hello&gt;<b>world</b></body>

`` CAT``

Este assistente concatena outros helpers, mesmo como TAG [ “”].

>>> print CAT('Here is a ', A('link', _href=URL()), ', and here is some ', B('bold text'), '.')
Here is a <a href="/app/default/index">link</a>, and here is some <b>bold text</b>.

`` CODE``

Este assistente executa da sintaxe para o Python, C, C ++, o código HTML e py4web, e é preferível a `` PRE`` para listagens de código. `` CODE`` também tem a capacidade de criar links para a documentação py4web API.

Aqui está um exemplo de destacar seções de código Python.

>>> print CODE('print "hello"', language='python').xml()
<table><tr style="vertical-align:top;">
  <td style="min-width:40px; text-align: right;"><pre style="
        font-size: 11px;
        font-family: Bitstream Vera Sans Mono,monospace;
        background-color: transparent;
        margin: 0;
        padding: 5px;
        border: none;
        color: #A0A0A0;
    ">1.</pre></td><td><pre style="
        font-size: 11px;
        font-family: Bitstream Vera Sans Mono,monospace;
        background-color: transparent;
        margin: 0;
        padding: 5px;
        border: none;
        overflow: auto;
        white-space: pre !important;
"><span style="color:#185369; font-weight: bold">print </span>
  <span style="color: #FF9966">"hello"</span></pre></td></tr></table>

Aqui está um exemplo semelhante para HTML

>>> print CODE('<html><body>[[=request.env.remote_add]]</body></html>',
...     language='html')
<table>...<code>...
<html><body>[[=request.env.remote_add]]</body></html>
...</code>...</table>

Estes são os argumentos padrão para o `` CODE`` helper:

CODE("print 'hello world'", language='python', link=None, counter=1, styles={})

Os valores suportados para o argumento `` language`` são “python”, “html_plain”, “c”, “cpp”, “py4web”, e “html”. Os “HTML” interpreta linguagem tags como código “py4web”, enquanto “html_plain” não.

Se um `` valor link`` é especificado, por exemplo “/ examples / global / vars /”, referências py4web API no código estão ligados a documentação no link URL. Por exemplo “pedido” estaria ligada à “/ examples / / global vars / request”. No exemplo acima, o URL de ligação é tratada pelo “vars” acção na “global.py” controlador que é distribuído como parte do py4web “exemplos” aplicação.

O argumento `` counter`` é utilizado para a numeração de linha. Ele pode ser configurado para qualquer um dos três valores diferentes. Pode ser `` None`` para não números de linha, um valor numérico especificando o número inicial, ou uma string. Se o contador está definido para uma cadeia, ele é interpretado como um aviso, e não há números de linha.

O argumento styles`` é um pouco complicado. Se você olhar para o HTML gerado acima, que contém uma tabela com duas colunas, e cada coluna tem um estilo próprio declarou em linha usando CSS. Os `` atributos styles`` permite substituir esses dois estilos CSS. Por exemplo:

CODE(..., styles={'CODE':'margin: 0;padding: 5px;border: none;'})

O atributo `` styles`` deve ser um dicionário, e permite que duas chaves possíveis: `` CODE`` para o estilo do código atual, e `` LINENUMBERS`` para o estilo da coluna esquerda, que contém a linha números. Lembre-se que estes estilos substituir completamente os estilos padrão e não são simplesmente adicionados a eles.

`` Div``

Todos os helpers além de `` XML`` são derivados de `` div`` e herdar seus métodos básicos.

>>> print DIV('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<div id="0" class="test">&lt;hello&gt;<b>world</b></div>

`` EM``

Insiste no seu conteúdo.

>>> print EM('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<em id="0" class="test">&lt;hello&gt;<b>world</b></em>

`` Form``

Este é um dos mais helpers importantes. Na sua forma mais simples, ele só faz um `` <form> … </ form> tag ``, mas porque helpers são objetos e ter conhecimento do que eles contêm, eles podem processar formulários enviados (por exemplo, executar a validação de os campos). Isso será discutido em detalhes no Capítulo 12 <# capítulo-12> __.

>>> print FORM(INPUT(_type='submit'), _action='', _method='post')
<form enctype="multipart/form-data" action="" method="post">
<input type="submit" /></form>

O “enctype” é “multipart / form-data” por padrão.

O construtor de um `` Form``, e de `` SQLFORM``, também pode tomar um argumento especial chamado `` hidden``. Quando um dicionário é passado como `` hidden``, seus itens são convertidos em campos de entrada “escondido”. Por exemplo:

>>> print FORM(hidden=dict(a='b'))
<form enctype="multipart/form-data" action="" method="post">
<input value="b" type="hidden" name="a" /></form>

`` H1``, `` h2``, `` H3``, `` H4``, `` H5``, `` H6``

Estes helpers são para títulos dos parágrafos e subtítulos:

>>> print H1('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<h1 id="0" class="test">&lt;hello&gt;<b>world</b></h1>

`` HTML``

Este assistente é um pouco diferente. Além de fazer os `` <html> `` tag, que precederá a tag com um fio doctype.

>>> print HTML(BODY('<hello>', XML('<b>world</b>')))
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><body>&lt;hello&gt;<b>world</b></body></html>

O auxiliar HTML também leva alguns argumentos opcionais adicionais que têm o seguinte padrão:

HTML(..., lang='en', doctype='transitional')

onde DOCTYPE pode ser ‘rigorosa’, ‘transitório’, ‘do conjunto de quadros’, ‘html5’, ou uma corda tipo de documento completo.

`` I``

Este assistente torna o seu conteúdo em itálico.

>>> print I('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<i id="0" class="test">&lt;hello&gt;<b>world</b></i>

`` IMG``

Ele pode ser usado para imagens incorporar em HTML:

>>> print IMG(_src='http://example.com/image.png', _alt='test')
 ![](http://example.com/image.ong){ alt="rest" }

Aqui é uma combinação de helpers A, IMG, e URL para a inclusão de uma imagem estática com um link:

>>> print A(IMG(_src=URL('static', 'logo.png'), _alt="My Logo"),
...   _href=URL('default', 'index'))
...
<a href="/myapp/default/index">
   ![](/myapp/static/logo.png){ alt="My Logo" }
</a>

`` INPUT``

Cria um `` <input … /> `` tag. Uma tag de entrada não pode conter outras tags, e é fechada por `` /> `` em vez de > ``. A tag de entrada tem um atributo opcional `` _type que pode ser definido como “texto” (o padrão), “enviar”, “caixa”, ou “rádio”.

>>> print INPUT(_name='test', _value='a')
<input value="a" name="test" />

Ele também leva um argumento especial opcional chamado “valor”, distinto <quotechar> _value “. Este último define o valor padrão para o campo de entrada; o ex define seu valor atual. Para uma entrada do tipo”text <quotechar>, os antigos substitui o último:

>>> print INPUT(_name='test', _value='a', value='b')
<input value="b" name="test" />

Para os botões de rádio, `` INPUT`` define seletivamente o “marcada” atributo:

>>> for v in ['a', 'b', 'c']:
...     print INPUT(_type='radio', _name='test', _value=v, value='b'), v
...
<input value="a" type="radio" name="test" /> a
<input value="b" type="radio" checked="checked" name="test" /> b
<input value="c" type="radio" name="test" /> c

e similarmente para caixas de seleção:

>>> print INPUT(_type='checkbox', _name='test', _value='a', value=True)
<input value="a" type="checkbox" checked="checked" name="test" />
>>> print INPUT(_type='checkbox', _name='test', _value='a', value=False)
<input value="a" type="checkbox" name="test" />

`` Label``

Ele é usado para criar uma tag rótulo para um campo de entrada.

>>> print LABEL('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<label id="0" class="test">&lt;hello&gt;<b>world</b></label>

`` LI``

Faz um item da lista e deve estar contido em um `` UL`` ou `` tag OL``.

>>> print LI('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<li id="0" class="test">&lt;hello&gt;<b>world</b></li>

`` OL``

Fica para a lista ordenada. A lista deve conter tags LI. `` Argumentos OL`` que não são `` objetos LI`` são automaticamente fechados em `` <li> … </ li> `` tags.

>>> print OL('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<ol id="0" class="test"><li>&lt;hello&gt;</li><li><b>world</b></li></ol>

`` OPTION``

Isso só deve ser usado como parte de um `` / `` combinação OPTION`` SELECT``.

>>> print OPTION('<hello>', XML('<b>world</b>'), _value='a')
<option value="a">&lt;hello&gt;<b>world</b></option>

Como no caso de `` INPUT``, py4web fazer uma distinção entre <quotechar> _value <quotechar> (o valor da opção), e “valor” (o valor atual do delimitador selecionar). Se forem iguais, a opção é “selecionado”.

>>> print SELECT('a', 'b', value='b'):
<select>
<option value="a">a</option>
<option value="b" selected="selected">b</option>
</select>

`` P``

Isto é para marcar um parágrafo.

>>> print P('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<p id="0" class="test">&lt;hello&gt;<b>world</b></p>

`` PRE``

Gera um `` <pre> … </ pre> `` tag para exibir texto pré-formatado. O `` CODE`` auxiliar é geralmente preferível para listagens de código.

>>> print PRE('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<pre id="0" class="test">&lt;hello&gt;<b>world</b></pre>

`` SCRIPT``

Esta é incluir ou vincular um script, como JavaScript. O conteúdo entre as tags é processado como um comentário HTML, para o benefício dos navegadores realmente antigos.

>>> print SCRIPT('alert("hello world");', _type='text/javascript')
<script type="text/javascript"><!--
alert("hello world");
//--></script>

`` SELECT``

Faz um `` <selecionar> … </ select> tag . Isto é usado com o `` helper OPTION. Esses `` argumentos SELECT`` que não são `` objetos OPTION`` são automaticamente convertidas em opções.

>>> print SELECT('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<select id="0" class="test">
<option value="&lt;hello&gt;">&lt;hello&gt;</option>
<option value="&lt;b&gt;world&lt;/b&gt;"><b>world</b></option>
</select>

`` SPAN``

Semelhante a `` div`` mas utilizado para marcação em linha (em vez de bloco) conteúdo.

>>> print SPAN('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<span id="0" class="test">&lt;hello&gt;<b>world</b></span>

`` STYLE``

Semelhante ao script, mas usadas para incluir ou código do link CSS. Aqui, o CSS está incluído:

>>> print STYLE(XML('body {color: white}'))
<style><!--
body { color: white }
//--></style>

e aqui ela está ligada:

>>> print STYLE(_src='style.css')
<style src="style.css"><!--
//--></style>

`` TABLE``, `` TR``, `` TD``

Estas tags (juntamente com o opcional `` THEAD`` e `` helpers TBODY``) são utilizados para tabelas de construção HTML.

>>> print TABLE(TR(TD('a'), TD('b')), TR(TD('c'), TD('d')))
<table><tr><td>a</td><td>b</td></tr><tr><td>c</td><td>d</td></tr></table>

`` `` TR`` espera conteúdo TD``; argumentos que não são `` objetos TD`` são convertidos automaticamente.

>>> print TABLE(TR('a', 'b'), TR('c', 'd'))
<table><tr><td>a</td><td>b</td></tr><tr><td>c</td><td>d</td></tr></table>

É fácil converter uma matriz de Python em uma tabela HTML usando `` * `` notação argumentos de função do Python, que mapeia os elementos da lista para os argumentos da função posicionais.

Aqui, vamos fazê-lo linha por linha:

>>> table = [['a', 'b'], ['c', 'd']]
>>> print TABLE(TR(*table[0]), TR(*table[1]))
<table><tr><td>a</td><td>b</td></tr><tr><td>c</td><td>d</td></tr></table>

Aqui nós fazer todas as linhas de uma só vez:

>>> table = [['a', 'b'], ['c', 'd']]
>>> print TABLE(*[TR(*rows) for rows in table])
<table><tr><td>a</td><td>b</td></tr><tr><td>c</td><td>d</td></tr></table>

`` TBODY``

Isto é usado para linhas tag contidos no corpo de mesa, em oposição a linhas de cabeçalho ou de rodapé. É opcional.

>>> print TBODY(TR('<hello>'), _class='test', _id=0)
<tbody id="0" class="test"><tr><td>&lt;hello&gt;</td></tr></tbody>

`` TEXTAREA``

Este assistente faz uma <textarea> … </ textarea> tag ``.

>>> print TEXTAREA('<hello>', XML('<b>world</b>'), _class='test')
<textarea class="test" cols="40" rows="10">&lt;hello&gt;<b>world</b></textarea>

A única ressalva é que o seu “valor” opcional substitui seu conteúdo (HTML interna)

>>> print TEXTAREA(value="<hello world>", _class="test")
<textarea class="test" cols="40" rows="10">&lt;hello world&gt;</textarea>

`` TH``

Este é utilizado em vez de `` TD`` em cabeçalhos de tabela.

>>> print TH('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<th id="0" class="test">&lt;hello&gt;<b>world</b></th>

`` THEAD``

Isto é usado para linhas de cabeçalho da tabela tag.

>>> print THEAD(TR(TH('<hello>')), _class='test', _id=0)
<thead id="0" class="test"><tr><th>&lt;hello&gt;</th></tr></thead>

`` TITLE``

Isto é usado para marcar o título de uma página em um cabeçalho HTML.

>>> print TITLE('<hello>', XML('<b>world</b>'))
<title>&lt;hello&gt;<b>world</b></title>

`` TR``

Palavras chave uma linha da tabela. Ele deve ser processado dentro de uma tabela e conter `` <td> … </ td> `` tags. `` Argumentos TR`` que não são `` objetos TD`` serão convertidos automaticamente.

>>> print TR('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<tr id="0" class="test"><td>&lt;hello&gt;</td><td><b>world</b></td></tr>

`` TT``

Etiquetas de texto como máquina de escrever texto (monoespaçada).

>>> print TT('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<tt id="0" class="test">&lt;hello&gt;<b>world</b></tt>

`` UL``

Significa uma lista desordenada e deve conter `` itens LI``. Se o seu conteúdo não é marcado como `` LI``, `` UL`` faz isso automaticamente.

>>> print UL('<hello>', XML('<b>world</b>'), _class='test', _id=0)
<ul id="0" class="test"><li>&lt;hello&gt;</li><li><b>world</b></li></ul>

`` URL``

O helper URL é documentado em * Capítulo 4 URL ../04*

Helpers personalizados

`` TAG``

Às vezes você precisa para gerar tags XML personalizados. py4web fornece `` TAG``, um gerador de tag universal.

[[=TAG.name('a', 'b', _c='d')]]

gera o seguinte XML

<name c="d">ab</name>

Argumentos “a”, “b” e “d” são automaticamente escapou; usar o `` helper XML`` para suprimir esse comportamento. Usando `` TAG`` você pode gerar HTML / XML marcas já não fornecidos pela API. As etiquetas podem ser aninhados, e são serializados com `` str () `` Uma sintaxe é equivalente.:

[[=TAG['name']('a', 'b', c='d')]]

Se o objeto TAG é criado com um nome vazio, ele pode ser usado para concatenar várias cadeias e helpers HTML juntos sem inseri-los em uma tag ao redor, mas este uso é obsoleto. Use o `` helper CAT`` vez.

Tags com auto-fechamento podem ser geradas com o helper TAG. O noma da tag deve terminar com um “/”.

[[=TAG['link/'](_href='http://py4web.com')]]

gera o seguinte XML:

<link ref="http://py4web.com"/>

Note que `` TAG`` é um objecto, e `` `` TAG.name`` ou TAG [ “nome”] `` é uma função que retorna uma classe auxiliar temporária.

`` BEAUTIFY``

`` BEAUTIFY`` é usado para representações de construção HTML de objetos compostos, incluindo listas, tuplas e dicionários:

[[=BEAUTIFY({"a": ["hello", XML("world")], "b": (1, 2)})]]

`` BEAUTIFY`` retorna um objeto serializado XML-like to XML, com uma representação de vista agradável de seu argumento construtor. Neste caso, a representação XML:

{"a": ["hello", XML("world")], "b": (1, 2)}

retribuirá como:

<table>
<tr><td>a</td><td>:</td><td>hello<br />world</td></tr>
<tr><td>b</td><td>:</td><td>1<br />2</td></tr>
</table>

Server-side * DOM * e análise

`` elements``

O auxiliar DIV e todos os auxiliares derivados fornecer a métodos de pesquisa `` element`` e `` elements``.

`` Retornos element`` o primeiro elemento filho correspondente a uma condição especificada (ou nenhum, se não fósforo).

`` Elements`` retorna uma lista de todas as crianças correspondentes.

** elemento ** e elementos ** ** usar a mesma sintaxe para especificar a condição de correspondência, que permite três possibilidades que podem ser misturados e combinados: jQuery-como expressões, jogo pelo valor do atributo exato, fósforo usando expressões regulares.

Aqui está um exemplo simples:

>>> a = DIV(DIV(DIV('a', _id='target', _class='abc')))
>>> d = a.elements('div#target')
>>> d[0][0] = 'changed'
>>> print a
<div><div><div id="target" class="abc">changed</div></div></div>

O argumento sem nome de `` elements`` é uma string, que pode conter: o nome de uma tag, o id de uma tag precedida por um símbolo de libra, a classe precedido por um ponto, o valor explícito de um atributo em parêntesis rectos.

Aqui estão 4 maneiras equivalentes para pesquisar a tag anterior id:

d = a.elements('#target')
d = a.elements('div#target')
d = a.elements('div[id=target]')
d = a.elements('div', _id='target')

Aqui estão 4 maneiras equivalentes para pesquisar a tag anterior por classe:

d = a.elements('.abc')
d = a.elements('div.abc')
d = a.elements('div[class=abc]')
d = a.elements('div', _class='abc')

Qualquer atributo pode ser usado para localizar um elemento (e não apenas `` id`` e `` class``), incluindo vários atributos (o elemento função pode demorar vários argumentos nomeados), mas apenas o primeiro elemento correspondente será devolvido.

Usando o jQuery sintaxe “div # target” é possível especificar vários critérios de pesquisa separadas por uma vírgula:

a = DIV(SPAN('a', _id='t1'), DIV('b', _class='c2'))
d = a.elements('span#t1, div.c2')

ou equivalente

a = DIV(SPAN('a', _id='t1'), DIV('b', _class='c2'))
d = a.elements('span#t1', 'div.c2')

Se o valor de um atributo é especificado usando um argumento de nome, pode ser uma string ou uma expressão regular:

a = DIV(SPAN('a', _id='test123'), DIV('b', _class='c2'))
d = a.elements('span', _id=re.compile('test\d{3}')

Um especial chamado argumento do DIV (e derivados) helpers é `` find``. Ele pode ser usado para especificar um valor de pesquisa ou uma expressão regular de busca no conteúdo de texto do tag. Por exemplo:

>>> a = DIV(SPAN('abcde'), DIV('fghij'))
>>> d = a.elements(find='bcd')
>>> print d[0]
<span>abcde</span>

ou

>>> a = DIV(SPAN('abcde'), DIV('fghij'))
>>> d = a.elements(find=re.compile('fg\w{3}'))
>>> print d[0]
<div>fghij</div>

`` Components``

Aqui está um exemplo de listar todos os elementos em uma string html:

>>> html = TAG('<a>xxx</a><b>yyy</b>')
>>> for item in html.components:
...     print item
...
<a>xxx</a>
<b>yyy</b>

`` `` Parent`` e siblings``

`` Parent`` retorna o pai do elemento de corrente.

>>> a = DIV(SPAN('a'), DIV('b'))
>>> s = a.element('span')
>>> d = s.parent
>>> d['_class']='abc'
>>> print a
<div class="abc"><span>a</span><div>b</div></div>
>>> for e in s.siblings(): print e
<div>b</div>

Substituir elementos

Elementos que são combinados também podem ser substituídos ou removidos, especificando o argumento `` replace``. Observe que uma lista dos elementos correspondentes originais ainda é devolvido como de costume.

>>> a = DIV(SPAN('x'), DIV(SPAN('y'))
>>> b = a.elements('span', replace=P('z')
>>> print a
<div><p>z</p><div><p>z</p></div>

`` Replace`` pode ser um que pode ser chamado. Neste caso, será passado o elemento original e é esperado para retornar o elemento de substituição:

>>> a = DIV(SPAN('x'), DIV(SPAN('y'))
>>> b = a.elements('span', replace=lambda t: P(t[0])
>>> print a
<div><p>x</p><div><p>y</p></div>

Se `` substituir = None``, os elementos correspondentes serão completamente removidas.

>>> a = DIV(SPAN('x'), DIV(SPAN('y'))
>>> b = a.elements('span', replace=None)
>>> print a
<div></div>

`` flatten``

O método flatten recursivamente serializa o conteúdo dos filhos de um determinado elemento em texto normal (sem etiquetas):

>>> a = DIV(SPAN('this', DIV('is', B('a'))), SPAN('test'))
>>> print a.flatten()
thisisatest

Nivelar pode ser passado um argumento opcional, `` render``, isto é, uma função que processa / achata o conteúdo utilizando um protocolo diferente. Aqui está um exemplo para serializar algumas tags em sintaxe Markmin wiki:

>>> a = DIV(H1('title'), P('example of a ', A('link', _href='#test')))
>>> from gluon.html import markmin_serializer
>>> print a.flatten(render=markmin_serializer)
# titles

example of *a link *

No momento da escrita nós fornecemos `` markmin_serializer`` e `` markdown_serializer``.

Análise

O objeto TAG é também um XML / HTML parser. Pode ler o texto e converter em uma estrutura de árvore de helpers. Isto permite a manipulação usando a API acima:

>>> html = '<h1>Title</h1><p>this is a <span>test</span></p>'
>>> parsed_html = TAG(html)
>>> parsed_html.element('span')[0]='TEST'
>>> print parsed_html
<h1>Title</h1><p>this is a <span>TEST</span></p>

Layout da página

Visualizações pode estender e incluir outros pontos de vista em uma estrutura de árvore.

Por exemplo, podemos pensar em uma visão “index.html” que se estende “layout.html” e inclui “body.html”. Ao mesmo tempo, “layout.html” pode incluir “header.html” e “footer.html”.

A raiz da árvore é o que chamamos de exibição de layout. Assim como qualquer outro arquivo de modelo HTML, você pode editá-lo usando a interface administrativa py4web. O nome do arquivo “layout.html” é apenas uma convenção.

Aqui está uma página minimalista que se estende a visão “layout.html” e inclui o ponto de vista “page.html”:

[[extend 'layout.html']]
<h1>Hello World</h1>
[[include 'page.html']]

O arquivo de layout estendido deve conter um `` [[incluir]] `` directiva, algo como:

<html>
  <head>
    <title>Page Title</title>
  </head>
  <body>
    [[include]]
  </body>
</html>

Quando o ponto de vista é chamado, o (layout) vista alargada é carregado, e o ponto de vista chamando substitui a `` [[incluir]] `` directiva dentro da disposição. O processamento continua de forma recursiva até que todo `` `` extend`` e directivas include`` tenham sido processados. O modelo resultante é então traduzido em código Python. Note, quando um aplicativo é bytecode compilado, é este código Python que é compilado, não a visão original próprios arquivos. Assim, a versão bytecode compilado de um determinado ponto de vista é um único arquivo .pyc que inclui o código Python não apenas para o arquivo de exibição original, mas para toda a sua árvore de pontos de vista estendidas e incluídos.

`` Extend``, `` include``, `` block`` e `` super`` são directivas especiais do template, e não comandos Python.

Qualquer conteúdo ou código que precede a `` [[estender …]] `` directiva será inserido (e, portanto, executado) antes do início do conteúdo / código da vista estendida. Embora este não é normalmente usado para inserir conteúdo HTML real antes de o conteúdo da exibição estendida, ele pode ser útil como um meio para definir variáveis ​​ou funções que você deseja disponibilizar para a exibição estendida. Por exemplo, considere uma visão “index.html”:

[[sidebar_enabled=True]]
[[extend 'layout.html']]
<h1>Home Page</h1>

e um trecho de “layout.html”:

[[if sidebar_enabled:]]
    <div id="sidebar">
        Sidebar Content
    </div>
[[pass]]

Porque o `` atribuição sidebar_enabled`` em “index.html” vem antes do `` extend``, essa linha é inserido antes do início do “layout.html”, fazendo com que `` qualquer lugar sidebar_enabled`` disponível dentro do “layout. html”código (uma versão um pouco mais sofisticada deste é usado no bem-vindo ** ** app).

Também é importante ressaltar que as variáveis ​​retornadas pela função de controlador estão disponíveis não só na vista principal da função, mas em todos os seus pontos de vista estendidas e incluídos também.

O argumento de um `` `` extend`` ou include`` (isto é, o nome vista alargada ou incluído) possa ser uma variável Python (embora não uma expressão Python). No entanto, este impõe uma limitação - vistas que usar variáveis ​​no `` extend`` ou `` declarações include`` não pode ser bytecode compilado. Como mencionado acima, vista compilado-bytecode incluem toda a árvore de pontos de vista estendidas e incluídos, de modo que o específica estendida e vistas incluídos deve ser conhecido em tempo de compilação, que não é possível se os nomes de exibição são variáveis ​​(cujos valores não são determinados até run Tempo). Porque vistas bytecode compilação pode fornecer um impulso de velocidade significativa, utilizando variáveis ​​em `` extend`` e `` include`` geralmente deve ser evitada, se possível.

Em alguns casos, uma alternativa para usar uma variável em um `` include`` é simplesmente para colocar regulares `` [[incluem …]] `` directivas dentro de um `` se … bloco else``.

[[if some_condition:]]
[[include 'this_view.html']]
[[else:]]
[[include 'that_view.html']]
[[pass]]

O código acima não apresenta qualquer problema para a compilação bytecode porque há variáveis ​​estão envolvidas. Note, no entanto, que o bytecode compilado vista realmente irá incluir o código Python para ambos “this_view.html” e “that_view.html”, embora apenas o código para um desses pontos de vista serão executadas, dependendo do valor de `` some_condition ``.

Tenha em mente, isso só funciona para `` include`` - você não pode colocar `` [[estender …]] `` directivas dentro `` se … blocos else``.

Layouts são usados ​​para página encapsular comunalidade (cabeçalhos, rodapés, menus), e embora eles não são obrigatórios, eles vão fazer a sua aplicação mais fácil de escrever e manter. Em particular, sugerimos escrever layouts que aproveitam as seguintes variáveis ​​que podem ser definidas no controlador. Usando estas variáveis ​​bem conhecidas irá ajudar a tornar seus layouts intercambiáveis:

response.title
response.subtitle
response.meta.author
response.meta.keywords
response.meta.description
response.flash
response.menu
response.files

Exceto para `` menu`` e `` files``, estas são todas as cordas e seu significado deve ser óbvia.

`` Menu response.menu`` está uma lista de 3-tuplas ou 4-tuplas. Os três elementos são: o nome do link, um booleano representando se o link está ativo (é o elo atual), e o URL da página vinculada. Por exemplo:

response.menu = [('Google', False, 'http://www.google.com', []),
                 ('Index',  True,  URL('index'), [])]

O quarto elemento tupla é um sub-menu de opcionais.

`` Response.files`` é uma lista de arquivos CSS e JS que são necessários pelo sua página.

Também recomendamos que você usa:

[[include 'py4web_ajax.html']]

na cabeça HTML, uma vez que irá incluir as bibliotecas jQuery e definir algumas funções JavaScript compatível com versões anteriores para efeitos especiais e Ajax. “Py4web_ajax.html” inclui os `` tag response.meta`` na vista, base jQuery, o datepicker calendário, e todos CSS necessário e JS `` response.files``.

Layout de página padrão

O “views / layout.html” que acompanha o aplicativo andaimes py4web ** boas-vindas ** (despojado de algumas partes opcionais) é bastante complexa, mas tem a seguinte estrutura:

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
  <title>[[=response.title or request.application]]</title>
  ...
  <script src="[[=URL('static', 'js/modernizr.custom.js')]]"></script>

  [[
  response.files.append(URL('static', 'css/py4web.css'))
  response.files.append(URL('static', 'css/bootstrap.min.css'))
  response.files.append(URL('static', 'css/bootstrap-responsive.min.css'))
  response.files.append(URL('static', 'css/py4web_bootstrap.css'))
  ]]

  [[include 'py4web_ajax.html']]

  [[
  # using sidebars need to know what sidebar you want to use
  left_sidebar_enabled = globals().get('left_sidebar_enabled', False)
  right_sidebar_enabled = globals().get('right_sidebar_enabled', False)
  middle_columns = {0:'span12', 1:'span9', 2:'span6'}[
    (left_sidebar_enabled and 1 or 0)+(right_sidebar_enabled and 1 or 0)]
  ]]

  [[block head]][[end]]
</head>

<body>
  <!-- Navbar ================================================== -->
  <div class="navbar navbar-inverse navbar-fixed-top">
    <div class="flash">[[=response.flash or '']]</div>
    <div class="navbar-inner">
      <div class="container">
        [[=response.logo or '']]
        <ul id="navbar" class="nav pull-right">
          [[='auth' in globals() and auth.navbar(mode="dropdown") or '']]
        </ul>
        <div class="nav-collapse">
          [[if response.menu:]]
          [[=MENU(response.menu)]]
          [[pass]]
        </div><!--/.nav-collapse -->
      </div>
    </div>
  </div><!--/top navbar -->

  <div class="container">
    <!-- Masthead ================================================== -->
    <header class="mastheader row" id="header">
        <div class="span12">
            <div class="page-header">
                <h1>
                    [[=response.title or request.application]]
                    <small>[[=response.subtitle or '']]</small>
                </h1>
            </div>
        </div>
    </header>

    <section id="main" class="main row">
        [[if left_sidebar_enabled:]]
        <div class="span3 left-sidebar">
            [[block left_sidebar]]
            <h3>Left Sidebar</h3>
            <p></p>
            [[end]]
        </div>
        [[pass]]

        <div class="[[=middle_columns]]">
            [[block center]]
            [[include]]
            [[end]]
        </div>

        [[if right_sidebar_enabled:]]
        <div class="span3">
            [[block right_sidebar]]
            <h3>Right Sidebar</h3>
            <p></p>
            [[end]]
        </div>
        [[pass]]
    </section><!--/main-->

    <!-- Footer ================================================== -->
    <div class="row">
        <footer class="footer span12" id="footer">
            <div class="footer-content">
                [[block footer]] <!-- this is default footer -->
                ...
                [[end]]
            </div>
        </footer>
    </div>

  </div> <!-- /container -->

  <!-- The javascript =============================================
       (Placed at the end of the document so the pages load faster) -->
  <script src="[[=URL('static', 'js/bootstrap.min.js')]]"></script>
  <script src="[[=URL('static', 'js/py4web_bootstrap.js')]]"></script>
  [[if response.google_analytics_id:]]
    <script src="[[=URL('static', 'js/analytics.js')]]"></script>
    <script type="text/javascript">
    analytics.initialize({
      'Google Analytics':{trackingId:'[[=response.google_analytics_id]]'}
    });</script>
  [[pass]]
</body>
</html>

Existem algumas características deste layout padrão que tornam muito fácil de usar e personalizar:

  • Ele é escrito em HTML5 e usa a biblioteca “Modernizr” para compatibilidade com versões anteriores. O layout real inclui algumas declarações condicionais extras exigidos pelo IE e eles são omitidos por brevidade.

  • Ele exibe tanto `` response.title`` e `` response.subtitle`` que pode ser definido em um modelo ou um controlador. Se eles não estão definidos, adota o nome do aplicativo como título.

  • Ele inclui o arquivo `` py4web_ajax.html`` no cabeçalho que gerou todas as declarações de importação da ligação e de script.

  • Ele usa uma versão modificada do Twitter Bootstrap para layouts flexíveis que funciona em dispositivos móveis e colunas reorganiza para caber telas pequenas.

  • Ele usa “analytics.js” para se conectar ao Google Analytics.

  • O `` [[= auth.navbar (…)]] `` exibe uma recepção para o usuário atual e links para as funções de autenticação, como login, logout, registro, alteração de senha, etc. dependendo do contexto. `` Auth.navbar`` é uma fábrica auxiliar e a sua saída podem ser manipulados como qualquer outro auxiliar. É colocado em uma expressão para verificar a existência de auth definição, as avalia a expressão ‘’ no caso de auth é indefinido.

  • O `` [[= MENU (response.menu)]] `` exibe a estrutura do menu como `` <ul> … </ ul> ``.

  • `` [[Incluir]] `` é substituído pelo conteúdo da vista que se prolonga, quando a página é processada.

  • Por padrão, ele usa uma de três colunas condicional (a esquerda e barras laterais direitas pode ser desligado com as vistas que se estendem)

  • Ele usa as seguintes classes: page-header, principal, rodapé.

  • Ele contém os seguintes blocos: cabeça, left_sidebar, centro, right_sidebar, rodapé.

Em vista, você pode ativar e personalizar barras laterais da seguinte forma:

[[left_sidebar_enabled=True]]
[[extend 'layout.html']]

This text goes in center

[[block left_sidebar]]
This text goes in sidebar
[[end]]

Personalizando o layout padrão

Personalizando o layout padrão sem edição é fácil, porque a aplicação de boas-vindas é baseado no Twitter Bootstrap que está bem documentado e suporta temas. Em py4web quatro arquivos estáticos que são relevantes para o estilo:

  • “Css / py4web.css” contém estilos py4web específicos

  • “Css / bootstrap.min.css” contém o estilo CSS Twitter Bootstrap

  • “Css / py4web_bootstrap.css”, que substitui alguns estilos Bootstrap para se conformar às necessidades py4web.

  • “js / bootstrap.min.js”, que inclui as bibliotecas para efeitos de menu, modais, painéis.

Para alterar as cores e imagens de fundo, tente anexar o seguinte código ao header layout.html:

<style>
body { background: url('images/background.png') repeat-x #3A3A3A; }
a { color: #349C01; }
.page-header h1 { color: #349C01; }
.page-header h2 { color: white; font-style: italic; font-size: 14px;}
.statusbar { background: #333333; border-bottom: 5px #349C01 solid; }
.statusbar a { color: white; }
.footer { border-top: 5px #349C01 solid; }
</style>

Claro que você também pode substituir completamente o “layout.html” e arquivos “py4web.css” com o seu próprio.

Desenvolvimento móvel

Embora o layout.html padrão é projetado para ser compatível com telemóvel, pode-se às vezes é preciso usar diferentes pontos de vista quando uma página é visitada por um dispositivo móvel.

Para tornar a desenvolver para desktop e dispositivos móveis mais fáceis, py4web inclui o `` @ mobilize`` decorador. Este decorador é aplicado a ações que devem ter uma visão normal e uma exibição móvel. Isso é demonstrado aqui:

from gluon.contrib.user_agent_parser import mobilize
@mobilize
def index():
    return dict()

Observe que o decorador deve ser importada antes de usá-lo em um controlador. Quando a função “index” é chamado a partir de um browser normal (computador de mesa), py4web tornará o dicionário retornado usando a exibição “[controller] /index.html”. No entanto, quando ele é chamado por um dispositivo móvel, o dicionário vai ser processado por “[controller] /index.mobile.html”. Observe que visualizações móveis têm a extensão “mobile.html”.

Alternativamente, você pode aplicar a seguinte lógica para fazer todos os pontos de vista móvel amigável:

if request.user_agent().is_mobile:
    response.view.replace('.html', '.mobile.html')

A tarefa de criar os <quotechar> *. Mobile.html <quotechar> vista é deixada para o desenvolvedor, mas sugerimos usando o plugin “jQuery Mobile” que torna a tarefa muito fácil.

Funções em vista

Considere isso “layout.html”:

<html>
  <body>
    [[include]]
    <div class="sidebar">
      [[if 'mysidebar' in globals():]][[mysidebar()]][[else:]]
        my default sidebar
      [[pass]]
    </div>
  </body>
</html>

e este ponto de vista que se prolonga

[[def mysidebar():]]
my new sidebar!!!
[[return]]
[[extend 'layout.html']]
Hello World!!!

Repare que a função é definida antes do `` [[estender …]] `` declaração - Isto resulta na função que está sendo criado antes do código “layout.html” é executado, assim que a função pode ser chamado em qualquer lugar dentro “layout. html”, mesmo antes do` [[incluir]] . Observe também a função está incluída na vista alargada sem a ` = `` prefixo.

O código gera o seguinte resultado:

<html>
  <body>
    Hello World!!!
    <div class="sidebar">
      my new sidebar!!!
    </div>
  </body>
</html>

Observe que a função é definida em HTML (embora ele também poderia conter código Python) para que `` response.write`` é usado para gravar o seu conteúdo (a função não retornar o conteúdo). É por isso que o layout chama a função de visão utilizando `` [[mysidebar ()]] `` `` em vez de [[= mysidebar ()]] ``. Funções definidas desta forma pode ter argumentos.

Blocos em vista

O caminho principal para fazer uma vista mais modular é usando `` [[bloco …]] `` s e este mecanismo é uma alternativa para o mecanismo discutido na secção anterior.

Para entender como isso funciona, considere aplicativos baseado no bem-vindo andaimes aplicativo, que tem um layout.html vista. Este ponto de vista é estendida pela vista `` padrão / index.html`` via `` [[estender “layout.html”]] ``. O conteúdo do layout.html predefinir certos blocos com determinado conteúdo padrão, e estes são, portanto, incluídos em default / index.html.

Você pode substituir esses blocos de conteúdo padrão, colocando o seu novo conteúdo dentro do mesmo nome do bloco. A localização do bloco no layout.html não é alterado, mas o conteúdo é.

Aqui está uma versão Simplificado. Imagine isto é “layout.html”:

<html>
  <body>
    [[include]]
    <div class="sidebar">
      [[block mysidebar]]
        my default sidebar (this content to be replaced)
      [[end]]
    </div>
  </body>
</html>

e isto é um simples que se estende vista `` padrão / index.html``:

[[extend 'layout.html']]
Hello World!!!
[[block mysidebar]]
my new sidebar!!!
[[end]]

Ele gera a saída seguinte, quando o teor é fornecido pelo bloco sobre-montada na vista estendendo-se, ainda a DIV envolvente e classe vem de layout.html. Isso permite que a consistência entre os pontos de vista:

<html>
  <body>
    Hello World!!!
    <div class="sidebar">
        my new sidebar!!!
    </div>
  </body>
</html>

O verdadeiro layout.html define um número de blocos úteis, e você pode facilmente adicionar mais para coincidir com o layout seu desejo.

Você pode ter muitos blocos, e se um bloco está presente na exibição estendida, mas não na visão estendendo, o conteúdo da visão ampliada é usado. Além disso, observe que, ao contrário com as funções, não é necessário definir blocos antes do `` [[estender …]] `` - mesmo se definido após o `` extend``, eles podem ser usados ​​para fazer substituições em qualquer lugar a vista estendida.

Dentro de um bloco, você pode usar a expressão `` [[Super]] `` para incluir o conteúdo do pai. Por exemplo, se substituir o acima estendendo vista com:

[[extend 'layout.html']]
Hello World!!!
[[block mysidebar]]
[[super]]
my new sidebar!!!
[[end]]

nós temos:

<html>
  <body>
    Hello World!!!
    <div class="sidebar">
        my default sidebar
        my new sidebar!
    </div>
  </body>
</html>