Export of ATContent Types with GSXML to the Filesystem
======================================================

Ramon Bartl <ramonski@ramonski.de>
Copyright (c) 2006-2007 InQuant GmbH

Abstract
--------
The GSXML is a Product that generates XML out of Plones ATContent Types and
implements GenericSetup's Interfaces to walk through folders and export the
files to e.g. the Filesystem or whatever specific export context we have.

Introduction
------------
The export of content to the filesystem describes the first usecase for our
GSXML Product. This method has many advantages for persistent storage::

    1. We can create the same structure like we have in Plone folder,
       documents, subfolder...
    2. Mostly we have enough free space and mostly even the rights to
       read/write data to
    3. we can see the result directly

Ok, sounds nice, but for our little test here, we don't use the filesystem to
read/write data. Instead we take a dictionary that holds our data. With the
filename as key and the content as value.


A simple export context that holds the exported data in a dictionary
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The context implements GenericSetup's IExportContext::

    >>> import os
    >>> from zope.interface import implements
    >>> from Products.GenericSetup.interfaces import IExportContext

The writeDataFile() Function writes the Data into a dictionary. In this case
the filename will be the key and the text, which is the content of the file,
will be the value:

'filename' -- the unqualified name of the file

'text' -- the content of the file

'content_type' -- the MIMEtype of the file

'subdir' -- if passed, is a path to a subdirectory / folder in which to write
    the file; if not passed, write the file to the root of the target

Ok, now the code::

    >>> class DummyExportContext(object):
    ...     implements( IExportContext )
    ...
    ...     def __init__(self):
    ...         self.brain={}
    ...
    ...     def writeDataFile(self, filename, text, content_type, subdir=None):
    ...         if subdir is not None:
    ...             fn = os.path.join( subdir, filename )
    ...         else:
    ...             fn = filename
    ...
    ...         self.brain[fn] = text


Some Dummy Content
------------------

We need some data that we can export: let's put everything in a "export"
folder::

    >>> self.setRoles(('Manager'),)
    >>> self.portal.invokeFactory("Folder", "export")
    'export'
    >>> ef = self.portal["export"]

    >>> ef.invokeFactory('Document', id='doc1', title='Test Page 1',
    ... text='<html> <body> a test page </body> </html>')
    'doc1'

    >>> ef.invokeFactory('Document', id='doc2', title='Test Page 2',
    ... text='<html> <body> another test page </body> </html>')
    'doc2'

    >>> ef.invokeFactory('Folder', id='subfolder', title='Test Folder 1')
    'subfolder'

    >>> ef.subfolder.invokeFactory('Document', id='doc3', title='Test Page 3',
    ... text='<html> <body> a test page in a subfolder </body> </html>')
    'doc3'

    >>> ef.subfolder.invokeFactory('Document', id='doc4', title='Test Page 4',
    ... text='<html> <body> a test page in a subfolder </body> </html>')
    'doc4'

    >>> ef.subfolder.invokeFactory('Document', id='doc5', title='Test Page 5',
    ... text='<html> <body> a test page in a subfolder </body> </html>')
    'doc5'

    >>> ef.objectIds()
    ['doc1', 'doc2', 'subfolder']



The Export Step
---------------

Now that we have a context that saves our data into a dictionary, we need an
exporter that generates the XML out of our dummy ATContentTypes and uses our
context to save the data::

    >>> from collective.plone.gsxml.content import XMLContentFSExporter
    >>> ex = XMLContentFSExporter( ef )

The XMLContentFSExporter implements GenericSetup's IFilesystemExporter
interface::

    >>> from Products.GenericSetup.interfaces import IFilesystemExporter
    >>> IFilesystemExporter.providedBy( ex )
    True

    >>> from zope.interface.verify import verifyObject
    >>> verifyObject( IFilesystemExporter, ex )
    True


The final step::

    >>> ec = DummyExportContext()
    >>> ex.export(ec, "structure", False)
    >>> ec.brain.keys()
    ['structure/export/doc2.xml', 'structure/export/subfolder.xml', ...'structure/export/subfolder/doc3.xml']

::

  vim: set ts=4 sw=4 expandtab filetype=rst:
