Ejemplo n.º 1
0
  def load(cls, name, parent_dir=None):
    """
    Loads a Python site template from a Python source file. Ensures that the
    loaded module has a `render()` function. The template will be searched for
    in the statigen templates directory or relative to the *parent_dir*.
    """

    parent_dir = parent_dir or os.getcwd()
    templates_dir = path.join(path.dir(__file__), 'templates')

    def find_template():
      for dirname in [parent_dir, templates_dir]:
        for choice in [name, name + '.py', path.join(name, 'site-template.py')]:
          filename = path.join(dirname, choice)
          if path.isfile(filename):
            return filename

    filename = find_template()
    if not filename:
      # TODO: Proper exception type
      raise ValueError('Template not found: {!r}'.format(name))

    with open(filename) as fp:
      code = fp.read()

    module = types.ModuleType(path.base(name))
    module.__file__ = filename

    six.exec_(compile(code, filename, 'exec'), vars(module))
    if not callable(getattr(module, 'render', None)):
      # TODO: Proper exception type
      raise ValueError('Template {!r} has no render() function or render is not callable'.format(name))

    return cls(module)
Ejemplo n.º 2
0
def main(argv=None, prog=None):
  parser = get_argument_parser(prog)
  args = parser.parse_args(argv)

  if not args.config and path.isfile('.statigen.toml'):
    args.config = '.statigen.toml'
  if args.config:
    with open(args.config) as fp:
      config = toml.load(fp)
  else:
    config = {}
  config = Config(config)

  if args.build_directory:
    config['statigen.buildDirectory'] = args.build_directory
  if args.template:
    config['statigen.template'] = args.template

  site_template = PythonSiteTemplate.load(config.get('statigen.template', 'default/docs'))
  context = Context(
    config = config,
    site_template = site_template,
    content_loader = import_class(config.get('contentLoader', __name__ + '.MarkdownTomlContentLoader'))(),
    content_renderer = import_class(config.get('contentRenderer', __name__ + '.MarkdownJinjaContentRenderer'))(),
    template_renderer = import_class(config.get('templateRenderer', __name__ + '.JinjaTemplateRenderer'))()
  )
  site_template.render(context)

  if args.open:
    import webbrowser
    webbrowser.open(path.join(config['statigen.buildDirectory'], 'index.html'))

  if args.watch:
    import time, threading
    import watchdog.events, watchdog.observers
    build_dir = path.abs(config['statigen.buildDirectory'])
    changed = threading.Event()
    class Handler(watchdog.events.FileSystemEventHandler):
      def on_any_event(self, event):
        rel = path.rel(path.abs(event.src_path), build_dir)
        if not path.issub(rel):  # Not an event in the build directory
          changed.set()
    observer = watchdog.observers.Observer()
    observer.schedule(Handler(), path=config['statigen.contentDirectory'], recursive=True)
    observer.schedule(Handler(), path=context.site_template.get_main_directory(context), recursive=True)
    observer.schedule(Handler(), path=context.project_directory, recursive=True)
    observer.start()
    try:
      while True:
        if changed.is_set():
          print()
          print('File changed, rebuilding ...')
          print()
          site_template.render(context)
          changed.clear()
        time.sleep(0.1)
    finally:
      observer.stop()
    observer.join()
Ejemplo n.º 3
0
 def load_content_from_directory(self, directory):
   if not path.isabs(directory):
     content_directory = self.config['statigen.contentDirectory']
     directory = path.join(content_directory, directory)
   result = []
   for content in self.content_loader.load_content_from_directory(self, directory):
     self.site_template.content_loaded(self, content)
     result.append(content)
   return result
Ejemplo n.º 4
0
 def render_template(self, context, template, vars):
   paths = []
   paths.append(path.join(context.project_directory, 'templates'))
   paths.append(context.get_template_directory())
   loader = jinja2.FileSystemLoader(paths)
   env = jinja2.Environment(loader=loader)
   template = env.get_template(template)
   context.template_vars = vars
   return template.render(vars)
Ejemplo n.º 5
0
  def copy(self, url, source):
    """
    Copy the file or directory *source* from the site templates main directory
    so that it is available from the specified URL.
    """

    if path.isabs(source):
      choices = [source]
    else:
      parent_dirs = [self.site_template.get_main_directory(self)]
      parent_dirs += [self.project_directory]
      choices = [path.join(x, source) for x in parent_dirs]

    target = self.url_to_abs_filename(url, False)
    print('copying {} ==> {} ({})'.format(source, target, url))

    for current in choices:
      if path.exists(current):
        print('  from {}'.format(current))
        copy_tree(current, target)
Ejemplo n.º 6
0
 def find_template():
   for dirname in [parent_dir, templates_dir]:
     for choice in [name, name + '.py', path.join(name, 'site-template.py')]:
       filename = path.join(dirname, choice)
       if path.isfile(filename):
         return filename
Ejemplo n.º 7
0
 def get_template_directory(self, context):
   directory = getattr(self.module, 'template_directory', None)
   if directory is None:
     directory = path.join(path.dir(self.module.__file__), 'templates')
   return directory
Ejemplo n.º 8
0
 def load_content_from_directory(self, context, directory):
   for filename in os.listdir(directory):
     if filename.endswith('.md'):
       name = filename[:-3]
       filename = path.join(directory, filename)
       yield self._load_file(context, filename, name)