####### Loaders ####### Loaders are callables that accept location as input argument then return a :doc:`template object `: .. doctest:: >>> import piecutter >>> load = piecutter.LocalLoader(root=u'demo/simple') >>> with load(u'hello.txt') as template: ... print(template) Hello {who}! Loaders encapsulate communication with file storages, either local or remote. They can: * distinguish single files from directories * read contents of single files * get a dynamic tree template out of a directory * or get the static list of templates in a directory. The default loader of ``piecutter.Cutter`` is a ``piecutter.ProxyLoader``. *********** LocalLoader *********** ``piecutter.LocalLoader`` handles files in local filesystem. .. doctest:: >>> import piecutter >>> load = piecutter.LocalLoader(root='demo/simple') >>> with load('hello.txt') as template: ... print(template) Hello {who}! >>> with load('i-dont-exist.txt') as template: # Doctest: +ELLIPSIS ... print(template) Traceback (most recent call last): ... TemplateNotFound: ... And local directories: .. doctest:: >>> import piecutter >>> load = piecutter.LocalLoader(root='demo/simple') >>> print(load.tree('.')) [u'hello.txt', u'{who}.txt'] ********** HttpLoader ********** ``piecutter.HttpLoader`` handles files over HTTP. .. doctest:: >>> load = piecutter.HttpLoader() >>> location = 'https://raw.githubusercontent.com/diecutter/diecutter/0.7/demo/templates/greetings.txt' >>> with load(location) as template: ... print(template) {{ greetings|default('Hello') }} {{ name }}! ************ GithubLoader ************ ``piecutter.GithubLoader`` handles files in Github repository. .. code-block:: pycon >>> checkout_dir = os.path.join(temp_dir, 'github-checkout') >>> load = piecutter.GithubLoader(checkout_dir) >>> location = 'diecutter/diecutter/0.7/demo/templates/greetings.txt' >>> with load(location) as template: ... print(template) {{ greetings|default('Hello') }} {{ name }}! *********** ProxyLoader *********** ``piecutter.ProxyLoader`` delegates loading to specific implementation depending on location: * if location is a :doc:`Template object `, just return it. * if location is Python's text, try to detect scheme (fallback to "text://") then route to specific loader matching this scheme. * if location is file-like object, route to specific loader matching "fileobj://" scheme. Let's initialize a proxy with routes: .. doctest:: >>> load = piecutter.ProxyLoader( ... routes={ # The following are defaults. ... 'text': piecutter.TextLoader(), ... 'fileobj': piecutter.FileObjLoader(), ... 'file': piecutter.LocalLoader(), ... 'http': piecutter.HttpLoader(), ... 'https': piecutter.HttpLoader(), ... }) Then load templates from various locations: >>> location = u'Just raw text\n' >>> with load(location) as template: ... print(template) Just raw text >>> from StringIO import StringIO >>> location = StringIO('Content in some file-like object\n') >>> with load(location) as template: ... print(template) Content in some file-like object >>> location = 'file://demo/simple/hello.txt' >>> with load(location) as template: ... print(template) Hello {who}! >>> location = 'https://raw.githubusercontent.com/diecutter/diecutter/0.7/demo/templates/greetings.txt' >>> with load(location) as template: ... print(template) {{ greetings|default('Hello') }} {{ name }}! ************** Custom loaders ************** Loaders typically are classes that inherit from ``piecutter.Loader``. Feel free to write your own! .. autoclass:: piecutter.loaders.Loader :members: :undoc-members: :show-inheritance: :member-order: bysource