xmlSiteMakerPy
About | How it works | Examples | Download | Author

How it works
 

Site Generation
Page Generation
   Page class hierarchy
   Creating xml content
   Element class hierarchy
   Make transform
   Write result
Make Self Page Class

Site Generation

Site generation diagram

There is classes Page, PageFactory, SiteGenerator and PageRepository.

Main class SiteGenerator and function generate() it takes from PageRepository each pageId of site, and by this pageId take from PageFactory object of class Page, and call method generate() of class Page:

But PageFactory return not Page :). For pageId = 'fp' PageFactory return object of PageFP, for other: PageSite.
from PageFactory.py
  def getPageById( self, pageId ):
    if pageId == 'fp':
      return PageFP()
    return PageSite( pageId )

Some words about PageRepository he generate pageIdArray from pages.xml by xslt transformation pages2text.xsl (content/xslt/other/). But 'fp' dont exists in pages.xml it pageId adds by hands.
from PageRepository.py
  def __init__(self):
    self.pageIds = []
    self.initPageIds()
    self.pageIds.append( "fp" )

Page Generation

Page generation diagram

Page class hierarchy

There is hierarchy of pages:
Page classes diagram
Inheritance classes differs from Page only by constructor.

class Page makes next:

  1. make self xml-content
  2. make transformation by xslt
  3. write result

Creating xml content

Xml content are created by aggregation different xml sources.

xml-content start from
from Page.py
    self.xml = """<?xml version="1.0"?>
<page-of-site>
#add_elements_here#
</page-of-site>
"""

Class Page contain array of objects of class Element. They are added in constructors of inheritance classes ( PageBase, PageFP, PageSite).

Function makeXml() are dead simple:
from Page.py
  def makeXml( self ):
    for self.element in self.elements:
      self.element.makeContent()
      self.insertIntoXml()

Each object of class Element have attributes name and content. And in function insertIntoXml() by its name xml-content-of-page are replaced by content of element:
from Page.py
  def insertIntoXml( self ):
    import string
    name = '#' + self.element.getName() + '#'
    self.xml = string.replace( 
                    self.xml, 
                    name, 
                    self.element.getContent() 
               )

Element class hierarchy

Hierarchy of elements:
Element classes diagram
By manipulation this elements performs creation of xml-content-of-page.

F.e. class PageBase constructor:
from PageBase.py
  def __init__( self ):
    Page.__init__( self )
    self.elements.append( 
      ElementForStub( 
        { 'params': 
          { 'text': "#common#\n#pages#\n#banners#\n#add_elements_here#\n" }
        } 
      )
    )

    self.elements.append( 
      ElementFromFile(
        { "name": "common", 
          "params": { "fileName": "db-xml:common.xml" }
        }
      )
    )

    self.elements.append(
      ElementFromFile(
        { 'name': 'pages', 
          'params': { 'fileName': 'db-xml:pages.xml' }
        }
      )
    )

    self.elements.append(
      ElementFromFile(
        { 'name': 'banners', 
          'params': { 'fileName': 'db-xml:banners.xml' }
        }
      )
    )
Element ElementForStub replace #add_elements_here#, then each next element replace self token: first ElementFromFile replace #common# (which was added by previous ElementForStub element), second ElementFromFile replace #pages# (note different between params are passed in constructors).

Element ElementFromFile working with class Content which have function getContent():
from Content.py
  def getContent( self, fileRequest ):
    import string
    ( area, file ) = string.split( fileRequest, ':' )
    fileName = self.root + area + '/' + file
    self.file.setFileName( fileName )
    self.file.load()
    return self.file.getData()
where self.root are path to 'content' folder. In that folder (if you remember) we have 3 folders (directories): db-xml, pages, xslt.

And fileRequest for function getContent() are formed as {area}:{fileName}. F.e. if we want to get content of file pages.xml in directory db-xml, we must make call:
contentOfPagesXml = self.objContent.getContent( 'xml:pages.xml' ).
And by same manner to directory pages or xslt.

And again about PageBase.

As you may note element ElementForStub add token #add_elements_here# in xml-content-of-page. This mean that we have not finished xml-content. And we must to make inheritance from this class.

Let's inheritance PageFP class. His constructor:
from PageFP.py
  def __init__( self ):
    PageBase.__init__( self )

    self.pageId = 'index'

    self.elements.append(
      ElementForStub(
        { 'params': 
          { 'text' : "#page_content#\n#news#" }
        }
      )
    )

    self.elements.append(
      ElementFromFile(
        { 'name': 'page_content', 
          'params': { 'fileName': 'pages:fp.xml' }
        }
      )
    )

    self.elements.append(
      ElementFromFile(
        { 'name': 'news', 
          'params': { 'fileName': 'db-xml:news.xml' }
        }
      )
    )

    self.xsltName = 'fp-page.xsl'
As you may note in this case element ElementForStub (which replace token #add_elements_here#) dosnt have token #add_elements_here#, i.e. in result we have finished xml-content.

xml-content will be contained from files pages/fp.xml, db-xml/news.xml. And xslt transformation will be made by fp-page.xsl.

For Page-package class PageSite, constructor:
from PageSite.py
  def __init__( self, pageId ):
    PageBase.__init__( self )

    self.pageId = pageId

    self.elements.append(
      ElementForStub(
        { 'params':
          { 'text': "#page_id#\n#page_content#\n" }
        }
      )
    )

    self.elements.append( ElementPageId( pageId ) )

    self.elements.append(
      ElementFromFile(
        { 'name': 'page_content', 
          'params': { 'fileName': 'pages:' + pageId + '.xml' }
        }
      )
    )

    self.xsltName = 'site-page.xsl'
Note that there is element ElementPageId which add tag <pageId>.

After makeXml() we will have (I add comments):
from result of makeXml()
<?xml version="1.0"?>
<page-of-site>
<!-- xml-header and 'page-of-site' are from Page -->

<!-- 'common' was added in PageBase -->
  <!-- this is file '/content/db-xml/common.xml' -->
  <common>
    <year>2003</year>
    <name>xmlSiteMakerPy</name>
    <email>nemilya@mail.ru</email>
  </common>

<!-- 'pages' was added in PageBase -->
  <!-- this is file '/content/db-xml/pages.xml' -->
  <pages>
    <page id="123" name="Name" descr="Description"/>
    ...
  </pages>

<!-- 'pageId' was added in PageSite -->
  <!-- this parameter passed in constructor by PageFactory -->
  <pageId>about</pageId>


<!-- 'page-content' was added in PageSite -->
  <!-- this is file '/content/page/{pageId}.xml' -->
  <page-content>
  
  <p>
  This application for offline generation.
  From xml documents by xslt transformation.
  </p>
  
  <p>
   <sectionList/>
  </p>

  ...
  </page-content>

</page-of-site>

Make transform

Each class Page have attribute xsltName by which xml-content are transformed: PageFP - 'fp-page.xsl', PageSite - 'site-page.xsl'. You can see this in constructor.

Write result

For writing result there is class PageWriter. Class Page in function write() call it:
from Page.py
  def writePage( self ):
    self.pageWriter.setContent( self.page )
    self.pageWriter.setPageId( self.pageId )
    self.pageWriter.write()

Make Self Page Class

Of course you can write self class. Inheritance them from Page or PageBase. And add to PageFactory in function getPageById 'if' for your pageId.

Diagrams was maded by ObjectDomain R3.

 

2003, xmlSiteMakerPy, inem@hotbox.ru on top page | Examples >>

SourceForge.net Logo