diff piecrust/commands/builtin/scaffolding.py @ 187:d5b7c2a4ec9d

prepare: Add user-defined scaffolding templates. Any files found in `scaffold/pages` will be used as possible templates for the `chef prepare` command, in addition to the default ones.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 04 Jan 2015 15:49:31 -0800
parents 8355eb9dd8fe
children f130365568ff
line wrap: on
line diff
--- a/piecrust/commands/builtin/scaffolding.py	Sun Jan 04 15:48:29 2015 -0800
+++ b/piecrust/commands/builtin/scaffolding.py	Sun Jan 04 15:49:31 2015 -0800
@@ -3,6 +3,7 @@
 import re
 import io
 import time
+import glob
 import logging
 import textwrap
 from piecrust import RESOURCES_DIR
@@ -83,6 +84,8 @@
             raise Exception("No such page template: %s" % tpl_name)
 
         tpl_text = ext.getTemplate(ctx.app, tpl_name)
+        if tpl_text is None:
+            raise Exception("Error loading template: %s" % tpl_name)
         title = (metadata.get('slug') or metadata.get('path') or
                  'Untitled page')
         title = make_title(title)
@@ -101,7 +104,7 @@
 
 
 class DefaultPrepareTemplatesCommandExtension(ChefCommandExtension):
-    """ Provides the default scaffolding tempaltes to the `prepare`
+    """ Provides the default scaffolding templates to the `prepare`
         command.
     """
     def __init__(self):
@@ -125,6 +128,40 @@
             return fp.read()
 
 
+class UserDefinedPrepareTemplatesCommandExtension(ChefCommandExtension):
+    """ Provides user-defined scaffolding templates to the `prepare`
+        command.
+    """
+    def __init__(self):
+        super(UserDefinedPrepareTemplatesCommandExtension, self).__init__()
+        self.command_name = 'prepare'
+
+    def _getTemplatesDir(self, app):
+        return os.path.join(app.root_dir, 'scaffold/pages')
+
+    def supports(self, app):
+        return os.path.isdir(self._getTemplatesDir(app))
+
+    def getTemplateNames(self, app):
+        names = os.listdir(self._getTemplatesDir(app))
+        return map(lambda n: os.path.splitext(n)[0], names)
+
+    def getTemplateDescription(self, app, name):
+        return "User-defined template."
+
+    def getTemplate(self, app, name):
+        templates_dir = self._getTemplatesDir(app)
+        pattern = os.path.join(templates_dir, '%s.*' % name)
+        matches = glob.glob(pattern)
+        if not matches:
+            raise Exception("No such page scaffolding template: %s" % name)
+        if len(matches) > 1:
+            raise Exception(
+                    "More than one scaffolding template has name: %s" % name)
+        with open(matches[0], 'r', encoding='utf8') as fp:
+            return fp.read()
+
+
 class DefaultPrepareTemplatesHelpTopic(ChefCommandExtension):
     """ Provides help topics for the `prepare` command.
     """