Open main menu

Gramps β

Changes

Libhtml

4,594 bytes added, 03:31, 18 September 2015
no edit summary
=== '''Html class ===''' description and user guide.
This page contains a description of and user's guide for the The Html class. This class is useful for the preparation of Html pages and is found in the srcfollowing directory:* [https://github.com/gramps-project/gramps/tree/master/gramps/plugins/lib directory.master/gramps/plugins/lib/]
== Standard XHTML Template ==
When actually writing an XHTML page from Python, you need to keep track of where you are so that you can properly close each element that you open. With a complicated document, this is tricky and fragile. This is what prompted me to write an Html class that can manage the trickiness and hopefully increase the robustness of the result. The idea is to store the page data in a series of nested lists then provide the means to extract them in proper order (basically a insertion-order tree traversal) for output. Let's start with an example. A similar, standard template can be generated with the Html class like this:
1. from libhtml import Html, _XMLNS
2. _LANG = 'xml:lang="en-CA" lang="en-CA"'
4. _META2 = 'http-equiv="Content-Style-Type" content="text/css"'
5. p = Html('html', indent=False, xmlns=html._XMLNS, attr=_LANG)
6. p.addXML()
7. p.addDOCTYPE()
5. Instantiate a new Html object. The first, positional argument is the tag type, which defaults to 'html'. The two keyword arguments are not specifically recognized by the constructor and are passed into the tag that is generated as attributes. For example, if I just say:
>>> print Html('html', xmlns=libhtml._XMLNS, attr=_LANG)
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-CA" lang="en-CA"></html>
>>>
You would do the same thing with other attributes, such as "xml:lang" Practically speaking, there are currently only a handful of keywords that conflict with Python keywords or are syntactically invalid in Python.
== Usage Using the Html class ==
The Html class extends the built-in "list" class and so any methods you can use on a list will work with Html as well. The methods described below are those that have been specially enhanced to support the generation of HTML documents:
;indent
:Indent this object with respect to its parent, if parent exists. Default = True. Note that the indentation is cumulative. That is, the indentation of this object will be the sum of its indentation and that of its parent, if the parent is indented. This is useful for producing human-readable output though it should have no effect on browsers rendering the page.  :Options: :;indent=True (Default)::Indent the contents of this object with respect to its parent. :;indent=False::Do not indent the contents of this object with respect to its parent:;indent=None::Reset base indentation to the beginning of the line for this object and its children. Note that child objects will continue to obey the indentation specified when they are instantiated, but since they are relative to their parent, their indentation will be relative to the beginning of the line.
;inline
:Instruct the write() method to output the tag and all its contents (including any nested elements) as one string. Default is False which means call the output method once for the beginning and ending tags and once for each element contained therein, including sub-elements.
 
:Options:
 
:;inline=False (Default)
::Do not write this object and its children as a single string.
:;inline=True
::Write this element and all its contents (including any nested elements) as one string.
;close
:This element should be closed normally (e.g. <tag>...</tag>). Default is True.
 
:Options:
 
:;close=True (default)
::Close this element normally (e.g. <tag>...</tag>)
:;close=False
::Do not close this element normally. Use "self-close" instead (e.g. <tag.../>). Note that this is automatic for all tags that are defined in the standard to be self-closing.
;keyword1=arg1...
=== Extending your Html objects ===
The Html class overloads the typical list methods append(), extend(), "+" and "+=" to enable you to easily build up your page. All of the following examples are validuses of Html objects. Try them in an interactive Python session and use <object>.write() to view the results:
page foo = Html(indent=False) bar = Html('head') page foobar = foo + bar bar += Html('headmeta') page bar.extend('meta',bob="your uncle") bar.append('useless text in header') opa = Html('body') page foobar += opa opa = page opa + Html('div', id="my div", class_="my class") page.append("a random string) page opa += [ 'text beginning', Html('a','imbedded href',href="http://w3c.org"), "text following" ] p = Html('p')+ ['the quality of mercy is not strained','it falleth as the gentle dew from heaven'] '''Note:''' The Html class does not implement list operations by index (e.g. list[1]) or slice (e.g. list[1:2]). Use these at your own risk as they may cause unpredictable results.
Of course, if you like you can add preformatted tags:
page += '&lt;ul&gt;&lt;li&gt;one&lt;/li&gt;&lt;li&gt;two&lt;/li&gt;&lt;/ul&gt;'
since the object derives from list, but then you are responsible for properly closing your tags.
ButHowever, if the tag argument begins with a "<", the constructor assumes that it is a preformatted tag:
page += Html('<title>My Title</title>')
You can use these to build your own DOCTYPE statements. The last one is useful when starting a new document:
page = Html(xmlns=_XMLNS) ''Note:'' You must explicitly import these constants from the libhtml module. For example:  from libhtml import _XMLMS === Using the Html class as a context manager === As of Python version 2.5, a new statement has been added to enable you to program within a given context. The "with" statement accomplishes this for you. The Html class supports being used in the "with" statement. That means that you can write code like:  with Html('table') as table: with Html('tbody') as tbody: table += tbody with Html('tr') as trow: tbody += trow with Html('td') as tcell: trow += tcell tcell += 'foobar' which has the advantage that the indentation structure of your program will match the indentation structure of the htmlfile produced by the write() method. Note: If you want to use the "with" statement in programs that may run under Python version 2.5, you must include the following as the first executable statement of your module:  from __future__ import with_statement == Recommended approach == The Html class is versatile and there are many ways to use it to produce an HTML page. You can make your life easier, however, if you organize your work as described in this section. === Use Html.page to begin a new page === The Html.page function takes care of the HTML boilerplate that is needed for every valid HTML page. Start off like this:  page, head, body = Html.page(title="My title') You will then have three Html objects to use for the rest of your work. (Insert your own title text as desired.) === Add additional tags to the header === Many pages require additional tags to be added to the <head> ._XMLNS.. </head> section. These can easily be added like this:  head += Html('meta', name="author", content="Bill Shakespeare") head += Html('link', media="screen" href="../my.css" type="text/css" rel="stylesheet" === Build up the page body by divisions === Try to design the body of your document as a logical arrangement of divisions that refer to CSS styles. Instantiate each division separately:  div1 = Html('div', id="first_division", class_='div1class') div2 = Html('div', id="second_division", class_='div2class') When you have designed your divisions, add them to the page body:  body += div1 body += div2 Or, if you have man divisions, you can add them all at once like this:  body += [div1, div2] '''Note:''' by adding them as a list, the divisions are siblings within the body.  === Add content to your divisions === If you are adding content that is more or less fixed, just add it directly:  div1 += Html('p','division 1 content') div2 += Html('p','division 2 content') If you are adding content that you will need to build up, first instantiate a new object and add it to your division:  table1 = Html('table') div1 += table === Write out your completed page === When all content has been added to your page, write it out:  page.write(myoutputmethod())
== Static Methods ==
[]
>>> p
 
 
[[Category:Developers/General]]