Skip to content

Commit

Permalink
added:
Browse files Browse the repository at this point in the history
- initial widgets implementation

updated:
- centralized jinja2 filters and functions to widgets
- Engine.activate > Engine.preprocess, and its optional now
- templates and tests
  • Loading branch information
bow committed Apr 11, 2012
1 parent abb95da commit 90155e3
Show file tree
Hide file tree
Showing 19 changed files with 250 additions and 159 deletions.
52 changes: 40 additions & 12 deletions volt/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
from volt.utils import path_import


DEFAULT_CONF = 'default_conf'
DEFAULT_WIDGET = 'default_widgets'


class SessionConfig(object):

"""Container class for storing all configurations used in a Volt run.
Expand All @@ -55,7 +59,7 @@ class SessionConfig(object):
"""

def __init__(self, default_dir=os.path.dirname(__file__), \
start_dir=os.getcwd(), default_conf_name='default'):
start_dir=os.getcwd(), default_conf_name=DEFAULT_CONF):
"""Initializes SessionConfig.
default_dir -- Absolute directory path of the default configuration.
Expand All @@ -64,7 +68,8 @@ def __init__(self, default_dir=os.path.dirname(__file__), \
"""
self.py3 = (sys.version_info[0] > 2)
self.start_dir = start_dir
self._default = path_import(default_conf_name, default_dir)
self.default_dir = default_dir
self._default = path_import(default_conf_name, self.default_dir)
# set flag for lazy-loading
self._loaded = False

Expand Down Expand Up @@ -95,12 +100,19 @@ def _load(self):
self._default.VOLT.USER_CONF))[0]
user = path_import(user_conf_name, root_dir)

# name of config objects to get
target_configs = ['VOLT', 'SITE', 'JINJA2_FILTERS', 'JINJA2_TESTS', ]
self._default.VOLT.USER_WIDGET = os.path.join(root_dir, \
self._default.VOLT.USER_WIDGET)
widget_name = os.path.splitext(os.path.basename(\
self._default.VOLT.USER_WIDGET))[0]

# for combining default and user jinja2 filters and tests
_site_conf = getattr(self._default, 'SITE')
default_filters = getattr(_site_conf, 'FILTERS')
default_tests = getattr(_site_conf, 'TESTS')

# Configs to process is everything in default + anything in user
# not present in default
for item in target_configs:
for item in 'VOLT', 'SITE':
# load from default first and override if present in user
obj = getattr(self._default, item)
if hasattr(user, item):
Expand All @@ -118,20 +130,36 @@ def _load(self):
# set root dir as config in VOLT
setattr(self.VOLT, 'ROOT_DIR', root_dir)

# combine filters and tests
self.SITE.FILTERS = tuple(set(self.SITE.FILTERS + default_filters))
self.SITE.TESTS = tuple(set(self.SITE.TESTS + default_tests))

# and set the loaded flag to True here
# so we can start referring to the resolved configs
self._loaded = True

# set up jinja2 template environment in the SITE Config object
env = Environment(loader=FileSystemLoader(self.VOLT.TEMPLATE_DIR))

# pass jinja2 functions
config_jinja2 = {'filters': self.JINJA2_FILTERS, 'tests': self.JINJA2_TESTS}
for type in config_jinja2:
for func_name in config_jinja2[type]:
# env.filters or env.tests
target = getattr(env, type)
target[func_name] = config_jinja2[type][func_name]
# import filters and tests
default_widget = path_import(DEFAULT_WIDGET, self.default_dir)
try:
user_widget = path_import(widget_name, self.VOLT.ROOT_DIR)
except ImportError:
# pass if the user doesn't have any widget file
pass
else:
# set jinja2 functions
for type in 'FILTERS', 'TESTS':
for func_name in getattr(self.SITE, type):
# env.filters or env.tests
target = getattr(env, type.lower())
# user-defined functions take precedence
if hasattr(user_widget, func_name):
func = getattr(user_widget, func_name)
else:
func = getattr(default_widget, func_name)
target[func_name] = func

# setattr self jinja2 env
setattr(self.SITE, 'TEMPLATE_ENV', env)
Expand Down
31 changes: 11 additions & 20 deletions volt/config/default.py → volt/config/default_conf.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
"""
-------------------
volt.config.default
-------------------
------------------------
volt.config.default_conf
------------------------
Volt default configurations.
Expand All @@ -21,6 +21,9 @@
# Used to determine project root
USER_CONF = 'voltconf.py',

# User widget file name
USER_WIDGET = 'widgets.py',

# Directory paths for content files, templates, assets,
# and generated site relative to a project root
CONTENT_DIR = 'contents',
Expand All @@ -43,13 +46,6 @@
# Defaults to none
ENGINES = (),

# Plugins used in site generation
# Tuple of tuples, each containing a string for the plugin file name
# and list of engine names indicating which engine to target
# Run according to order listed here
# Defaults to none
PLUGINS = (('',[]),),

# Extra pages to write that are not controlled by an engine
# Examples: 404.html, index.html (if not already written by an engine)
# The tuple should list template names of these pages, which should
Expand All @@ -69,23 +65,18 @@
INDEX_HTML_ONLY = True,

# Logging level
# If set to logging.DEBUG, Volt will write logs to a file
# If set to 10, Volt will write logs to a file
# 30 is logging.WARNING
LOG_LEVEL = 30,

# Ignore patterns
# Filenames that match this pattern will not be copied from asset directory
# to site directory
IGNORE_PATTERN = '',
)

# Jinja2 filter function names
FILTERS = ('displaytime',),

# Built-in Jinja2 filters
JINJA2_FILTERS = Config(
# displays time according to the given format
displaytime = lambda time, format: time.strftime(format),
# Jinja2 test function names
TESTS = (),
)


# Built-in Jinja2 tests
JINJA2_TESTS = Config()
16 changes: 16 additions & 0 deletions volt/config/default_widgets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
"""
---------------------------
volt.config.default_widgets
---------------------------
Volt default widgets, and jinja2 filters and tests.
:copyright: (c) 2012 Wibowo Arindrarto <bow@bow.web.id>
:license: BSD
"""

def displaytime(time, format):
"""Jinja2 filter for displaying datetime objects according to format."""
return time.strftime(format)
2 changes: 1 addition & 1 deletion volt/engine/builtins/blog.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class BlogEngine(TextEngine):
# Config instance name in voltconf.py
USER_CONF_ENTRY = 'ENGINE_BLOG'

def activate(self):
def preprocess(self):
# sort units
self.sort_units()
# add prev and next permalinks so blog posts can link to each other
Expand Down
4 changes: 0 additions & 4 deletions volt/engine/builtins/plain.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@ class PlainEngine(TextEngine):
# Config instance name in voltconf.py
USER_CONF_ENTRY = 'ENGINE_PLAIN'

def activate(self):
# nothing to do prior to plugin run
pass

def dispatch(self):
# write them according to template
self.write_units()
12 changes: 7 additions & 5 deletions volt/engine/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ class Engine(LoggableMixin):
subclassing engine.
Any subclass of Engine must create a 'units' property and override the
activate and dispatch methods.
dispatch method. Optionally, the preprocess method may be overridden if any
unit processing prior to plugin run needs to be performed.
"""

Expand All @@ -81,11 +82,12 @@ class Engine(LoggableMixin):

def __init__(self):
self.config = Config(self.DEFAULTS)
self.widgets = {}
self.logger.debug('created: %s' % type(self).__name__)

@abc.abstractmethod
def activate(self):
"""Performs initial processing of resources into unit objects."""
def preprocess(self):
"""Performs initial processing of units before plugins are run."""
pass

@abc.abstractmethod
def dispatch(self):
Expand Down Expand Up @@ -384,7 +386,7 @@ def _write_items(self, items, template_path):
self.logger.error(message)
raise IOError(message)
else:
rendered = template.render(page=item, CONFIG=CONFIG)
rendered = template.render(page=item, widgets=self.widgets, CONFIG=CONFIG)
if sys.version_info[0] < 3:
rendered = rendered.encode('utf-8')
write_file(item.path, rendered)
Expand Down
Loading

0 comments on commit 90155e3

Please sign in to comment.