# Path: statik/common.py
# class YamlLoadable(object):
#     """Base class for objects that can be loaded from a YAML file or a
#     YAML string, passed through to the constructor."""
# 
#     def __init__(self, filename=None, from_string=None, encoding='utf-8', error_context=None):
#         # default to UTF-8
#         self.encoding = encoding
#         self.file_content = None
#         self.error_context = error_context or StatikErrorContext()
#         self.error_context.update(filename=filename)
# 
#         if filename is not None:
#             self.filename = filename
# 
#             with open(self.filename, mode='rt', encoding=self.encoding) as f:
#                 self.file_content = f.read()
# 
#         elif from_string is not None:
#             self.filename = None
#             self.file_content = from_string
# 
#         else:
#             raise MissingParameterError("filename", "from_string")
# 
#         # load the variables from the YAML file
#         self.vars = yaml.safe_load(self.file_content) if self.file_content else {}
#         if not isinstance(self.vars, dict):
#             self.vars = {}
#         else:
#             # strip out any extra whitespace from the variables
#             self.vars = dict_strip(self.vars)
# 
# Path: statik/context.py
# class StatikContext(object):
#     """For representing context in projects and views."""
# 
#     def __init__(
#             self,
#             initial=None,
#             static=None,
#             dynamic=None,
#             for_each=None
#         ):
#         self.initial = initial or dict()
#         self.static = underscore_var_names(
#             deepcopy(static or dict())
#         )
#         self.dynamic = underscore_var_names(
#             deepcopy(dynamic or dict())
#         )
#         self.for_each = underscore_var_names(
#             deepcopy(for_each or dict())
#         )
#         logger.debug("Created Statik context instance: %s", self)
# 
#     def __repr__(self):
#         return "StatikContext(initial=%s, static=%s, dynamic=%s, for_each=%s)" % (
#             self.initial, self.static, self.dynamic, self.for_each
#         )
# 
#     def __str__(self):
#         return repr(self)
# 
#     def build_dynamic(self, db, extra=None, safe_mode=False):
#         """Builds the dynamic context based on our current dynamic context entity and the given
#         database."""
#         result = dict()
#         for var, query in self.dynamic.items():
#             result[var] = db.query(query, safe_mode=safe_mode, additional_locals=extra)
#         return result
# 
#     def build_for_each(self, db, safe_mode=False, extra=None):
#         """Builds the for-each context."""
#         result = dict()
#         for var, query in self.for_each.items():
#             result[var] = db.query(
#                 query,
#                 additional_locals=extra,
#                 safe_mode=safe_mode
#             )
#         return result
# 
#     def build(self, db=None, safe_mode=False, for_each_inst=None, extra=None):
#         """Builds a dictionary that can be used as context for template rendering."""
#         result = copy(self.initial)
#         result.update(self.static)
#         if self.dynamic:
#             result.update(self.build_dynamic(db, extra=extra, safe_mode=safe_mode))
#         if self.for_each and for_each_inst:
#             result.update(self.build_for_each(db, safe_mode=safe_mode, extra=extra))
#         if isinstance(extra, dict):
#             result.update(extra)
#         return result


from copy import deepcopy, copy
from statik.common import YamlLoadable
from statik.errors import *
from statik.utils import *
from statik.context import StatikContext
import logging
        """Renders the given context using the specified database, returning a dictionary
        containing path segments and rendered view contents."""
        if not db:
            raise MissingParameterError(
                "db",
                context=self.error_context
            )
        rendered_views = dict()
        path_instances = db.query(self.path.query, safe_mode=safe_mode)
        extra_ctx = copy(extra_context) if extra_context else dict()

        for inst in path_instances:
            extra_ctx.update({
                self.path.variable: inst
            })
            ctx = context.build(
                db=db,
                safe_mode=safe_mode,
                for_each_inst=inst,
                extra=extra_ctx
            )
            inst_path = self.path.render(inst=inst, context=ctx)
            rendered_view = self.template.render(ctx)
            rendered_views = deep_merge_dict(
                rendered_views,
                dict_from_path(inst_path, final_value=rendered_view)
            )
        return rendered_views



# Path: statik/common.py
# class YamlLoadable(object):
#     """Base class for objects that can be loaded from a YAML file or a
#     YAML string, passed through to the constructor."""
# 
#     def __init__(self, filename=None, from_string=None, encoding='utf-8', error_context=None):
#         # default to UTF-8
#         self.encoding = encoding
#         self.file_content = None
#         self.error_context = error_context or StatikErrorContext()
#         self.error_context.update(filename=filename)
# 
#         if filename is not None:
#             self.filename = filename
# 
#             with open(self.filename, mode='rt', encoding=self.encoding) as f:
#                 self.file_content = f.read()
# 
#         elif from_string is not None:
#             self.filename = None
#             self.file_content = from_string
# 
#         else:
#             raise MissingParameterError("filename", "from_string")
# 
#         # load the variables from the YAML file
#         self.vars = yaml.safe_load(self.file_content) if self.file_content else {}
#         if not isinstance(self.vars, dict):
#             self.vars = {}
#         else:
#             # strip out any extra whitespace from the variables
#             self.vars = dict_strip(self.vars)
# 
# Path: statik/context.py
# class StatikContext(object):
#     """For representing context in projects and views."""
# 
#     def __init__(
#             self,
#             initial=None,
#             static=None,
#             dynamic=None,
#             for_each=None
#         ):
#         self.initial = initial or dict()
#         self.static = underscore_var_names(
#             deepcopy(static or dict())
#         )
#         self.dynamic = underscore_var_names(
#             deepcopy(dynamic or dict())
#         )
#         self.for_each = underscore_var_names(
#             deepcopy(for_each or dict())
#         )
#         logger.debug("Created Statik context instance: %s", self)
# 
#     def __repr__(self):
#         return "StatikContext(initial=%s, static=%s, dynamic=%s, for_each=%s)" % (
#             self.initial, self.static, self.dynamic, self.for_each
#         )
# 
#     def __str__(self):
#         return repr(self)
# 
#     def build_dynamic(self, db, extra=None, safe_mode=False):
#         """Builds the dynamic context based on our current dynamic context entity and the given
#         database."""
#         result = dict()
#         for var, query in self.dynamic.items():
#             result[var] = db.query(query, safe_mode=safe_mode, additional_locals=extra)
#         return result
# 
#     def build_for_each(self, db, safe_mode=False, extra=None):
#         """Builds the for-each context."""
#         result = dict()
#         for var, query in self.for_each.items():
#             result[var] = db.query(
#                 query,
#                 additional_locals=extra,
#                 safe_mode=safe_mode
#             )
#         return result
# 
#     def build(self, db=None, safe_mode=False, for_each_inst=None, extra=None):
#         """Builds a dictionary that can be used as context for template rendering."""
#         result = copy(self.initial)
#         result.update(self.static)
#         if self.dynamic:
#             result.update(self.build_dynamic(db, extra=extra, safe_mode=safe_mode))
#         if self.for_each and for_each_inst:
#             result.update(self.build_for_each(db, safe_mode=safe_mode, extra=extra))
#         if isinstance(extra, dict):
#             result.update(extra)
#         return result


# Path: statik/views.py
from copy import deepcopy, copy
from statik.common import YamlLoadable
from statik.errors import *
from statik.utils import *
from statik.context import StatikContext
import logging

        """Renders the given context using the specified database, returning a dictionary
        containing path segments and rendered view contents."""
        if not db:
            raise MissingParameterError(
                "db",
                context=self.error_context
            )
        rendered_views = dict()
        path_instances = db.query(self.path.query, safe_mode=safe_mode)
        extra_ctx = copy(extra_context) if extra_context else dict()

        for inst in path_instances:
            extra_ctx.update({
                self.path.variable: inst
            })
            ctx = context.build(
                db=db,
                safe_mode=safe_mode,
                for_each_inst=inst,
                extra=extra_ctx
            )
            inst_path = self.path.render(inst=inst, context=ctx)
            rendered_view = self.template.render(ctx)
            rendered_views = deep_merge_dict(
                rendered_views,
                dict_from_path(inst_path, final_value=rendered_view)
            )
        return rendered_views



class StatikView(YamlLoadable):