def test_plugins(self): text = """ --- title: Hey author: Me twitter: @me --- {%% extends "base.html" %%} {%% block main %%} Hi! I am a test template to make sure jinja2 generation works well with hyde. <span class="title">{{resource.meta.title}}</span> <span class="author">{{resource.meta.author}}</span> <span class="twitter">{{resource.meta.twitter}}</span> {%% endblock %%} """ index = File(self.SITE_PATH.child('content/blog/index.html')) index.write(text) self.setup_config(['**/*.html', 'media/css/*.css']) conf = {'plugins': ['hyde.ext.plugins.meta.MetaPlugin']} conf.update(self.config.to_dict()) s = Site(self.SITE_PATH, Config(sitepath=self.SITE_PATH, config_dict=conf)) g = Generator(s) g.generate_all() source = s.content.resource_from_relative_path('blog/index.html') target = File( s.config.deploy_root_path.child(source.relative_deploy_path)) left = source.source_file.read_all() right = target.read_all() assert left == right
def test_ignores_pattern_in_content(self): text = """ {% markdown %} Heading 1 === Heading 2 === {% endmarkdown %} """ about2 = File(TEST_SITE.child('content/about2.html')) about2.write(text) s = Site(TEST_SITE) s.load() res = s.content.resource_from_path(about2.path) assert res.is_processable s.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin'] gen = Generator(s) gen.generate_all() target = File(Folder(s.config.deploy_root_path).child('about2.html')) text = target.read_all() q = PyQuery(text) assert q("h1").length == 2 assert q("h1:nth-child(1)").text().strip() == "Heading 1" assert q("h1:nth-child(2)").text().strip() == "Heading 2"
def test_pages_of_one_content(self): expected_page1_content = dedent('''\ Another Sad Post /page2/pages_of_one.txt''') expected_page2_content = dedent('''\ A Happy Post /pages_of_one.txt /page3/pages_of_one.txt''') expected_page3_content = dedent('''\ An Angry Post /page2/pages_of_one.txt /page4/pages_of_one.txt''') expected_page4_content = dedent('''\ A Sad Post /page3/pages_of_one.txt ''') page1 = self.deploy.child('pages_of_one.txt') content = File(page1).read_all() assert expected_page1_content == content page2 = self.deploy.child('page2/pages_of_one.txt') content = File(page2).read_all() assert expected_page2_content == content page3 = self.deploy.child('page3/pages_of_one.txt') content = File(page3).read_all() assert expected_page3_content == content page4 = self.deploy.child('page4/pages_of_one.txt') content = File(page4).read_all() assert expected_page4_content == content
def test_url_cleaner(self): s = Site(TEST_SITE) cfg = """ plugins: - hyde.ext.plugins.urls.UrlCleanerPlugin urlcleaner: index_file_names: - about.html strip_extensions: - html append_slash: true """ s.config = Config(TEST_SITE, config_dict=yaml.load(cfg, Loader=yaml.FullLoader)) text = """ {% extends "base.html" %} {% block main %} <a id="index" href="{{ content_url('about.html') }}"></a> <a id="blog" href= "{{ content_url('blog/2010/december/merry-christmas.html') }}"></a> {% endblock %} """ about2 = File(TEST_SITE.child('content/test.html')) about2.write(text) gen = Generator(s) gen.generate_all() from pyquery import PyQuery target = File(Folder(s.config.deploy_root_path).child('test.html')) text = target.read_all() q = PyQuery(text) assert q('a#index').attr("href") == '/' assert q('a#blog').attr( "href") == '/blog/2010/december/merry-christmas'
def import_to_include(match): """ Converts a css import statement to include statemnt. """ if not match.lastindex: return '' path = match.groups(1)[0] afile = File( File(resource.source_file.parent.child( path)).fully_expanded_path) if len(afile.kind.strip()) == 0: afile = File(afile.path + '.styl') ref = self.site.content.resource_from_path(afile.path) if not ref: try: include = self.settings.args.include except AttributeError: include = False if not include: raise self.template.exception_class( "Cannot import from path [%s]" % afile.path) else: ref.is_processable = False return "\n" + \ self.template.get_include_statement(ref.relative_path) + \ "\n" return '@import "' + path + '"\n'
def test_textlinks(self): d = { 'objects': 'template/variables', 'plugins': 'plugins/metadata', 'sorter': 'plugins/sorter' } text = """ {%% markdown %%} [[!!img/hyde-logo.png]] * [Rich object model][hyde objects] and [overridable hierarchical metadata]([[ %(plugins)s ]]) thats available for use in templates. * Configurable [sorting][], filtering and grouping support. [hyde objects]: [[ %(objects)s ]] [sorting]: [[%(sorter)s]] {%% endmarkdown %%} """ site = Site(TEST_SITE) site.config.plugins = ['hyde.ext.plugins.text.TextlinksPlugin'] site.config.base_url = 'http://example.com/' site.config.media_url = '/media' tlink = File(site.content.source_folder.child('tlink.html')) tlink.write(text % d) print((tlink.read_all())) gen = Generator(site) gen.generate_all() f = File(site.config.deploy_root_path.child(tlink.name)) assert f.exists html = f.read_all() assert html for name, path in list(d.items()): assert site.config.base_url + quote(path) in html assert '/media/img/hyde-logo.png' in html
def test_multiple_levels(self): page_d = {'title': 'An even nicer title'} blog_d = {'author': 'Laks'} content_d = {'title': 'A nice title', 'author': 'Lakshmi Vyas'} site_d = { 'author': 'Lakshmi', 'twitter': 'lakshmivyas', 'nodemeta': 'meta.yaml' } text = """ --- title: %(title)s --- {%% extends "base.html" %%} {%% block main %%} Hi! I am a test template to make sure jinja2 generation works well with hyde. <span class="title">{{resource.meta.title}}</span> <span class="author">{{resource.meta.author}}</span> <span class="twitter">{{resource.meta.twitter}}</span> {%% endblock %%} """ about2 = File(TEST_SITE.child('content/blog/about2.html')) about2.write(text % page_d) content_meta = File(TEST_SITE.child('content/nodemeta.yaml')) content_meta.write(yaml.dump(content_d)) content_meta = File(TEST_SITE.child('content/blog/meta.yaml')) content_meta.write(yaml.dump(blog_d)) s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin'] s.config.meta = site_d gen = Generator(s) gen.generate_all() expected = {} expected.update(site_d) expected.update(content_d) expected.update(blog_d) expected.update(page_d) res = s.content.resource_from_path(about2.path) assert hasattr(res, 'meta') for k, v in list(expected.items()): assert hasattr(res.meta, k) assert getattr(res.meta, k) == v target = File( Folder(s.config.deploy_root_path).child('blog/about2.html')) text = target.read_all() q = PyQuery(text) for k, v in list(expected.items()): if k != 'nodemeta': assert v in q("span." + k).text()
def test_pages_of_one(self): pages = ['pages_of_one.txt', 'page2/pages_of_one.txt', 'page3/pages_of_one.txt', 'page4/pages_of_one.txt'] files = [File(self.deploy.child(p)) for p in pages] for f in files: assert f.exists page5 = File(self.deploy.child('page5/pages_of_one.txt')) assert not page5.exists
def test_context_providers_equivalence(self): import yaml events = """ 2011: - title: "one event" location: "a city" - title: "one event" location: "a city" 2010: - title: "one event" location: "a city" - title: "one event" location: "a city" """ events_dict = yaml.load(events, Loader=yaml.FullLoader) config_dict = dict(context=dict( data=dict(events1=events_dict), providers=dict(events2="events.yaml") )) text = """ {%% extends "base.html" %%} {%% block main %%} <ul> {%% for year, eventlist in %s %%} <li> <h1>{{ year }}</h1> <ul> {%% for event in eventlist %%} <li>{{ event.title }}-{{ event.location }}</li> {%% endfor %%} </ul> </li> {%% endfor %%} </ul> {%% endblock %%} """ File(TEST_SITE.child('events.yaml')).write(events) f1 = File(TEST_SITE.child('content/text1.html')) f2 = File(TEST_SITE.child('content/text2.html')) f1.write(text % "events1") f2.write(text % "events2") site = Site(TEST_SITE, Config(TEST_SITE, config_dict=config_dict)) site.load() gen = Generator(site) gen.generate_all() left = File(site.config.deploy_root_path.child(f1.name)).read_all() right = File(site.config.deploy_root_path.child(f2.name)).read_all() assert left == right
def setup_class(cls): cls.SITE_PATH = File(__file__).parent.child_folder( 'sites/test_jinja_with_config') cls.SITE_PATH.make() TEST_SITE_ROOT.copy_contents_to(cls.SITE_PATH) cls.config_file = File(cls.SITE_PATH.child('alternate.yaml')) with open(cls.config_file.path) as config: cls.config = Config(sitepath=cls.SITE_PATH, config_dict=yaml.load(config)) cls.SITE_PATH.child_folder('content').rename_to( cls.config.content_root)
def setUp(self): TEST_SITE.make() TEST_SITE.parent.child_folder('sites/test_jinja').copy_contents_to( TEST_SITE) TEST_SITE.child_folder('content/media/js').make() JS = TEST_SITE.child_folder('content/scripts').make() S1 = JS.child_folder('s1').make() S2 = JS.child_folder('s2').make() S3 = JS.child_folder('s3').make() File(COMBINE_SOURCE.child('script.1.js')).copy_to(S1) File(COMBINE_SOURCE.child('script.2.js')).copy_to(S2) File(COMBINE_SOURCE.child('script.3.js')).copy_to(S3)
def _generic_test_image(self, text): self.site.config.mode = "production" self.site.config.plugins = ['hyde.ext.plugins.images.ImageSizerPlugin'] tlink = File(self.site.content.source_folder.child('timg.html')) tlink.write(text) gen = Generator(self.site) gen.generate_all() f = File(self.site.config.deploy_root_path.child(tlink.name)) assert f.exists html = f.read_all() assert html return html
def test_can_execute_optipng(self): s = Site(TEST_SITE) s.config.mode = "production" s.config.plugins = ['hyde.ext.plugins.images.OptiPNGPlugin'] s.config.optipng = Expando(dict(args=dict(quiet=""))) source = File(TEST_SITE.child('content/media/images/hyde-lt-b.png')) target = File( Folder( s.config.deploy_root_path).child('media/images/hyde-lt-b.png')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists assert target.size < source.size
def assert_extended(self, s, txt, templ): content = (templ.strip() % txt).strip() bd = File(TEST_SITE.child('content/auto_extend.html')) bd.write(content) gen = Generator(s) gen.generate_resource_at_path(bd.path) res = s.content.resource_from_path(bd.path) target = File(s.config.deploy_root_path.child( res.relative_deploy_path)) assert target.exists text = target.read_all() q = PyQuery(text) assert q('title').text().strip() == txt.strip()
def test_can_uglify(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.js.UglifyPlugin'] s.config.mode = "production" source = TEST_SITE.child('content/media/js/jquery.js') target = File(Folder(s.config.deploy_root_path).child('media/js/jquery.js')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists expected = File(UGLIFY_SOURCE.child('expected-jquery.js')) # TODO: Very fragile. Better comparison needed. assert target.read_all() == expected.read_all()
def import_to_include(match): if not match.lastindex: return '' path = match.groups(1)[0] afile = File(resource.source_file.parent.child(path)) if len(afile.kind.strip()) == 0: afile = File(afile.path + '.less') ref = self.site.content.resource_from_path(afile.path) if not ref: raise self.template.exception_class( "Cannot import from path [%s]" % afile.path) ref.is_processable = False return self.template.get_include_statement(ref.relative_path)
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 == c.content_root_path.child_folder('xxx') assert c.media_url == TEST_SITE.child_folder('/media') assert c.deploy_root_path == Folder('~/deploy_site')
def test_scss(self): s = Site(TEST_SITE) s.config.mode = 'prod' s.config.plugins = ['hyde.ext.plugins.css.SassyCSSPlugin'] source = TEST_SITE.child('content/media/css/site.scss') target = File( Folder(s.config.deploy_root_path).child('media/css/site.css')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() expected_text = File(SCSS_SOURCE.child('expected-site.css')).read_all() assert_no_diff(expected_text, text)
def test_can_execute_less(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.css.LessCSSPlugin'] source = TEST_SITE.child('content/media/css/site.less') target = File( Folder(s.config.deploy_root_path).child('media/css/site.css')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() expected_text = File(LESS_SOURCE.child('expected-site.css')).read_all() assert text == expected_text return
def test_can_execute_rjs(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.js.RequireJSPlugin'] source = TEST_SITE.child('content/media/js/rjs.conf') target = File( Folder(s.config.deploy_root_path).child('media/js/app.js')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists text = target.read_all() expected_text = File(RJS_SOURCE.child('app.js')).read_all() assert text == expected_text return
def test_uglify_with_extra_options(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.js.UglifyPlugin'] s.config.mode = "production" s.config.uglify = Expando(dict(args={"nc":""})) source = TEST_SITE.child('content/media/js/jquery.js') target = File(Folder(s.config.deploy_root_path).child('media/js/jquery.js')) gen = Generator(s) gen.generate_resource_at_path(source) assert target.exists expected = File(UGLIFY_SOURCE.child('expected-jquery-nc.js')) # TODO: Very fragile. Better comparison needed. text = target.read_all() assert text.startswith("(function(")
def test_context_providers(self): site = Site( TEST_SITE, Config(TEST_SITE, config_dict={ "context": { "data": { "abc": "def" }, "providers": { "nav": "nav.yaml" } } })) nav = """ main: - home - articles - projects """ text = """ {% extends "base.html" %} {% block main %} {{nav}} {% for item in nav.main %} {{item}} {% endfor %} abc = {{ abc }} Hi! I am a test template to make sure jinja2 generation works well with hyde. {{resource.name}} {% endblock %} """ File(TEST_SITE.child('nav.yaml')).write(nav) site.load() resource = site.content.resource_from_path( TEST_SITE.child('content/about.html')) gen = Generator(site) resource.source_file.write(text) gen.generate_all() target = File(site.config.deploy_root_path.child(resource.name)) out = target.read_all() assert "abc = def" in out assert "home" in out assert "articles" in out assert "projects" in out
def thumb(self, defaults={}, width=None, height=None): """ Generate a thumbnail for the given image """ if width is None and height is None: width, height = defaults['width'], defaults['height'] im = Image.open(self.path) if im.mode != 'RGBA': im = im.convert('RGBA') # Convert to a thumbnail if width is None: # height is not None width = im.size[0]*height/im.size[1] + 1 elif height is None: # width is not None height = im.size[1]*width/im.size[0] + 1 im.thumbnail((width, height), Image.ANTIALIAS) # Prepare path path = os.path.join(os.path.dirname(self.get_relative_deploy_path()), "%s%s" % (defaults['prefix'], self.name)) target = File(Folder(self.site.config.deploy_root_path).child(path)) target.parent.make() if self.name.endswith(".jpg"): im.save(target.path, "JPEG", optimize=True, quality=75) else: im.save(target.path, "PNG", optimize=True) return Thumb(path, width=im.size[0], height=im.size[1])
def test_context(self): site = Site(TEST_SITE, Config(TEST_SITE, config_dict={ "context": { "data": { "abc": "def" } } })) text = """ {% extends "base.html" %} {% block main %} abc = {{ abc }} Hi! I am a test template to make sure jinja2 generation works well with hyde. {{resource.name}} {% endblock %} """ site.load() resource = site.content.resource_from_path( TEST_SITE.child('content/about.html')) gen = Generator(site) resource.source_file.write(text) gen.generate_all() target = File(site.config.deploy_root_path.child(resource.name)) assert "abc = def" in target.read_all()
def begin_site(self): """ Configuration example --------------------- #yaml suffix: - target_extension: - markdown - md output_extension: html - target_extension: - rst - md output_extension: html """ config = self.site.config if not hasattr(config, 'suffix'): return suffix_config = attrgetter('suffix')(config) for resource in self.site.content.walk_resources(): for conf in suffix_config: conf = conf.to_dict() target = conf.get('target_extension', []) output = conf.get('output_extension', 'html') if resource.source_file.kind in target: new_name = resource.source_file.name_without_extension if output: new_name += "." + output target_folder = File(resource.relative_deploy_path).parent resource.relative_deploy_path = target_folder.child( new_name)
def load(sitepath, ctx): """ Load context from config data and providers. """ context = {} try: context.update(ctx.data.__dict__) except AttributeError: # No context data found pass providers = {} try: providers.update(ctx.providers.__dict__) except AttributeError: # No providers found pass for provider_name, resource_name in providers.items(): res = File(Folder(sitepath).child(resource_name)) if res.exists: data = make_expando( yaml.load(res.read_all(), Loader=yaml.FullLoader)) context[provider_name] = data return context
def app(self): """ Gets the application path from the site configuration. If the path is not configured, attempts to guess the path from the sytem path environment variable. """ try: app_path = getattr(self.settings, 'app') except AttributeError: app_path = self.executable_name # Honour the PATH environment variable. if app_path is not None and not os.path.isabs(app_path): app_path = discover_executable(app_path, self.site.sitepath) if app_path is None: raise HydeException(self.executable_not_found_message) app = File(app_path) if not app.exists: raise HydeException(self.executable_not_found_message) return app
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 == c.content_root_path.child_folder('mmm') assert c.media_url == TEST_SITE.child_folder('/media') assert c.deploy_root_path == Folder('~/deploy_site')
def test_depends(self): s = Site(TEST_SITE) s.config.plugins = [ 'hyde.ext.plugins.meta.MetaPlugin', 'hyde.ext.plugins.depends.DependsPlugin' ] text = """ === depends: index.html === """ inc = File(TEST_SITE.child('content/inc.md')) inc.write(text) gen = Generator(s) gen.load_site_if_needed() gen.load_template_if_needed() def dateformat(x): return x.strftime('%Y-%m-%d') gen.template.env.filters['dateformat'] = dateformat gen.generate_resource_at_path(inc.name) res = s.content.resource_from_relative_path(inc.name) assert len(res.depends) == 1 assert 'index.html' in res.depends deps = list(gen.get_dependencies(res)) assert len(deps) == 3 assert 'helpers.html' in deps assert 'layout.html' in deps assert 'index.html' in deps
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 == c.content_root_path.child_folder('mmm') assert c.media_url == TEST_SITE.child_folder('/media') assert c.deploy_root_path == Folder('~/deploy_site')