@@ -116,12 +116,7 @@ class Engine(Application): | |||||
Creates a site object from the given sitepath and the config file. | Creates a site object from the given sitepath and the config file. | ||||
""" | """ | ||||
sitepath = Folder(Folder(sitepath).fully_expanded_path) | sitepath = Folder(Folder(sitepath).fully_expanded_path) | ||||
config_file = sitepath.child(config) | |||||
logger.info("Reading site configuration from [%s]", config_file) | |||||
conf = {} | |||||
with codecs.open(config_file, 'r', 'utf-8') as stream: | |||||
conf = yaml.load(stream) | |||||
config = Config(sitepath, conf) | |||||
config = Config(sitepath, config_file=config) | |||||
if deploy: | if deploy: | ||||
config.deploy_root = deploy | config.deploy_root = deploy | ||||
return Site(sitepath, config) | return Site(sitepath, config) |
@@ -43,7 +43,7 @@ hyde [-s </site/path>] [-v] create [-l <layout>] [-f] [-h] | |||||
While basic and test are really barebones, doc is the one that generates | While basic and test are really barebones, doc is the one that generates | ||||
this documentation and is completely usable. Hyde will get more layouts | this documentation and is completely usable. Hyde will get more layouts | ||||
as over time. | |||||
over time. | |||||
Hyde tries to locate the specified layout in the following folders: | Hyde tries to locate the specified layout in the following folders: | ||||
@@ -62,7 +62,7 @@ | |||||
<header class="banner clearfix"> | <header class="banner clearfix"> | ||||
{% block header -%} | {% block header -%} | ||||
<img src="{{ media_url('img/hyde-logo-128.png') }}"> | <img src="{{ media_url('img/hyde-logo-128.png') }}"> | ||||
<h1>hyde 1.0</h1> | |||||
<h1>hyde 0.6</h1> | |||||
<h3>static hotness</h3> | <h3>static hotness</h3> | ||||
{%- endblock %} | {%- endblock %} | ||||
</header> | </header> | ||||
@@ -0,0 +1,3 @@ | |||||
extends: site.yaml | |||||
mode: production | |||||
deploy_root: ../../../../hydepy.github.com |
@@ -3,8 +3,12 @@ | |||||
Contains data structures and utilities for hyde. | Contains data structures and utilities for hyde. | ||||
""" | """ | ||||
from hyde.fs import File, Folder | from hyde.fs import File, Folder | ||||
import codecs | |||||
import yaml | import yaml | ||||
from hyde.util import getLoggerWithNullHandler | |||||
logger = getLoggerWithNullHandler('hyde.engine') | |||||
class Expando(object): | class Expando(object): | ||||
""" | """ | ||||
A generic expando class that creates attributes from | A generic expando class that creates attributes from | ||||
@@ -69,7 +73,7 @@ class Config(Expando): | |||||
Represents the hyde configuration file | Represents the hyde configuration file | ||||
""" | """ | ||||
def __init__(self, sitepath, config_dict=None): | |||||
def __init__(self, sitepath, config_file=None, config_dict=None): | |||||
default_config = dict( | default_config = dict( | ||||
content_root='content', | content_root='content', | ||||
deploy_root='deploy', | deploy_root='deploy', | ||||
@@ -81,10 +85,31 @@ class Config(Expando): | |||||
plugins = [] | plugins = [] | ||||
) | ) | ||||
conf = dict(**default_config) | conf = dict(**default_config) | ||||
self.sitepath = Folder(sitepath) | |||||
conf.update(self.read_config(config_file)) | |||||
if config_dict: | if config_dict: | ||||
conf.update(config_dict) | conf.update(config_dict) | ||||
super(Config, self).__init__(conf) | super(Config, self).__init__(conf) | ||||
self.sitepath = Folder(sitepath) | |||||
def read_config(self, config_file): | |||||
""" | |||||
Reads the configuration file and updates this | |||||
object while allowing for inherited configurations. | |||||
""" | |||||
conf_file = self.sitepath.child( | |||||
config_file if | |||||
config_file else 'site.yaml') | |||||
conf = {} | |||||
if File(conf_file).exists: | |||||
logger.info("Reading site configuration from [%s]", conf_file) | |||||
with codecs.open(conf_file, 'r', 'utf-8') as stream: | |||||
conf = yaml.load(stream) | |||||
if 'extends' in conf: | |||||
parent = self.read_config(conf['extends']) | |||||
parent.update(conf) | |||||
conf = parent | |||||
return conf | |||||
@property | @property | ||||
def deploy_root_path(self): | def deploy_root_path(self): | ||||
@@ -1,7 +1,4 @@ | |||||
mode: development | mode: development | ||||
media_root:: media # Relative path from site root (the directory where this file exists) | media_root:: media # Relative path from site root (the directory where this file exists) | ||||
media_url: /media | media_url: /media | ||||
template: hyde.ext.jinja2 | |||||
widgets: | |||||
plugins: | |||||
aggregators: | |||||
template: hyde.ext.jinja2 |
@@ -1,4 +1,4 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# -*- coding: utf-8 -*- | |||||
""" | """ | ||||
Use nose | Use nose | ||||
`$ pip install nose` | `$ pip install nose` | ||||
@@ -108,7 +108,7 @@ def test_markdown_with_extensions(): | |||||
""" | """ | ||||
t = Jinja2Template(JINJA2.path) | t = Jinja2Template(JINJA2.path) | ||||
s = Site(JINJA2.path) | s = Site(JINJA2.path) | ||||
c = Config(JINJA2.path, dict(markdown=dict(extensions=['headerid']))) | |||||
c = Config(JINJA2.path, config_dict=dict(markdown=dict(extensions=['headerid']))) | |||||
s.config = c | s.config = c | ||||
t.configure(s) | t.configure(s) | ||||
html = t.render(source, {}).strip() | html = t.render(source, {}).strip() | ||||
@@ -43,7 +43,8 @@ def test_expando_update(): | |||||
assert x.a == 789 | assert x.a == 789 | ||||
assert x.f == "opq" | assert x.f == "opq" | ||||
TEST_SITE_ROOT = File(__file__).parent.child_folder('sites/test_jinja') | |||||
TEST_SITE = File(__file__).parent.child_folder('_test') | |||||
import yaml | import yaml | ||||
class TestConfig(object): | class TestConfig(object): | ||||
@@ -70,27 +71,65 @@ class TestConfig(object): | |||||
aggregators: | aggregators: | ||||
""" | """ | ||||
def setUp(self): | |||||
TEST_SITE.make() | |||||
TEST_SITE.parent.child_folder('sites/test_jinja').copy_contents_to(TEST_SITE) | |||||
def tearDown(self): | |||||
TEST_SITE.delete() | |||||
def test_default_configuration(self): | def test_default_configuration(self): | ||||
c = Config(sitepath=TEST_SITE_ROOT) | |||||
c = Config(sitepath=TEST_SITE, config_dict={}) | |||||
for root in ['content', 'layout', 'media']: | for root in ['content', 'layout', 'media']: | ||||
name = root + '_root' | name = root + '_root' | ||||
path = name + '_path' | path = name + '_path' | ||||
assert hasattr(c, name) | assert hasattr(c, name) | ||||
assert getattr(c, name) == root | assert getattr(c, name) == root | ||||
assert hasattr(c, path) | assert hasattr(c, path) | ||||
assert getattr(c, path) == TEST_SITE_ROOT.child_folder(root) | |||||
assert getattr(c, path) == TEST_SITE.child_folder(root) | |||||
assert hasattr(c, 'plugins') | assert hasattr(c, 'plugins') | ||||
assert len(c.plugins) == 0 | assert len(c.plugins) == 0 | ||||
assert c.deploy_root_path == TEST_SITE_ROOT.child_folder('deploy') | |||||
assert c.deploy_root_path == TEST_SITE.child_folder('deploy') | |||||
assert c.not_found == '404.html' | assert c.not_found == '404.html' | ||||
def test_conf1(self): | def test_conf1(self): | ||||
c = Config(sitepath=TEST_SITE_ROOT, config_dict=yaml.load(self.conf1)) | |||||
assert c.content_root_path == TEST_SITE_ROOT.child_folder('stuff') | |||||
c = Config(sitepath=TEST_SITE, config_dict=yaml.load(self.conf1)) | |||||
assert c.content_root_path == TEST_SITE.child_folder('stuff') | |||||
def test_conf2(self): | def test_conf2(self): | ||||
c = Config(sitepath=TEST_SITE_ROOT, config_dict=yaml.load(self.conf2)) | |||||
assert c.content_root_path == TEST_SITE_ROOT.child_folder('site/stuff') | |||||
assert c.media_root_path == TEST_SITE_ROOT.child_folder('mmm') | |||||
assert c.media_url == TEST_SITE_ROOT.child_folder('/media') | |||||
c = Config(sitepath=TEST_SITE, config_dict=yaml.load(self.conf2)) | |||||
assert c.content_root_path == TEST_SITE.child_folder('site/stuff') | |||||
assert c.media_root_path == TEST_SITE.child_folder('mmm') | |||||
assert c.media_url == TEST_SITE.child_folder('/media') | |||||
assert c.deploy_root_path == Folder('~/deploy_site') | |||||
def test_read_from_file_by_default(self): | |||||
File(TEST_SITE.child('site.yaml')).write(self.conf2) | |||||
c = Config(sitepath=TEST_SITE) | |||||
assert c.content_root_path == TEST_SITE.child_folder('site/stuff') | |||||
assert c.media_root_path == TEST_SITE.child_folder('mmm') | |||||
assert c.media_url == TEST_SITE.child_folder('/media') | |||||
assert c.deploy_root_path == Folder('~/deploy_site') | |||||
def test_read_from_specified_file(self): | |||||
File(TEST_SITE.child('another.yaml')).write(self.conf2) | |||||
c = Config(sitepath=TEST_SITE, config_file='another.yaml') | |||||
assert c.content_root_path == TEST_SITE.child_folder('site/stuff') | |||||
assert c.media_root_path == TEST_SITE.child_folder('mmm') | |||||
assert c.media_url == TEST_SITE.child_folder('/media') | |||||
assert c.deploy_root_path == Folder('~/deploy_site') | |||||
def test_extends(self): | |||||
another = """ | |||||
extends: site.yaml | |||||
mode: production | |||||
media_root: xxx | |||||
""" | |||||
File(TEST_SITE.child('site.yaml')).write(self.conf2) | |||||
File(TEST_SITE.child('another.yaml')).write(another) | |||||
c = Config(sitepath=TEST_SITE, config_file='another.yaml') | |||||
assert c.mode == 'production' | |||||
assert c.content_root_path == TEST_SITE.child_folder('site/stuff') | |||||
assert c.media_root_path == TEST_SITE.child_folder('xxx') | |||||
assert c.media_url == TEST_SITE.child_folder('/media') | |||||
assert c.deploy_root_path == Folder('~/deploy_site') | assert c.deploy_root_path == Folder('~/deploy_site') |