changeset 32:43091c9837bf

Fix problems with asset URLs.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 19 Aug 2014 14:30:19 -0700
parents 8c15fc45d712
children 62c7a97c8340
files piecrust/baking/baker.py piecrust/data/assetor.py piecrust/environment.py tests/mockutil.py tests/test_data_assetor.py
diffstat 5 files changed, 50 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/baking/baker.py	Tue Aug 19 12:48:00 2014 -0700
+++ b/piecrust/baking/baker.py	Tue Aug 19 14:30:19 2014 -0700
@@ -246,7 +246,7 @@
         # Get into bake mode.
         start_time = time.clock()
         self.app.config.set('baker/is_baking', True)
-        self.app.env.base_asset_url_format = '%site_root%%uri%'
+        self.app.env.base_asset_url_format = '%uri%'
 
         # Make sure the output directory exists.
         if not os.path.isdir(self.out_dir):
--- a/piecrust/data/assetor.py	Tue Aug 19 12:48:00 2014 -0700
+++ b/piecrust/data/assetor.py	Tue Aug 19 14:30:19 2014 -0700
@@ -1,3 +1,4 @@
+import re
 import os
 import os.path
 import logging
@@ -11,19 +12,24 @@
     pass
 
 
-def build_base_url(app, uri, assets_path):
+def build_base_url(app, uri, rel_assets_path):
     base_url_format = app.env.base_asset_url_format
-    site_root = app.config.get('site/root')
-    rel_path = os.path.relpath(assets_path, app.root_dir).replace('\\', '/')
+    rel_assets_path = rel_assets_path.replace('\\', '/')
+
+    # Remove any extension or pagination suffix from the URL, since
+    # we'll be copying assets into the 1st sub-page's folder.
     pretty = app.config.get('site/pretty_urls')
     if not pretty:
         uri, _ = os.path.splitext(uri)
-    uri = uri.lstrip('/')
+    pgn_suffix_re = app.config.get('__cache/pagination_suffix_re')
+    m = re.search(pgn_suffix_re, uri)
+    if m:
+        uri = uri[:m.start():]
+
     base_url = multi_replace(
             base_url_format,
             {
-                '%site_root%': site_root,
-                '%path%': rel_path,
+                '%path%': rel_assets_path,
                 '%uri%': uri})
     return base_url.rstrip('/') + '/'
 
@@ -74,7 +80,8 @@
         if not os.path.isdir(assets_dir):
             return
 
-        base_url = build_base_url(self._page.app, self._uri, assets_dir)
+        rel_assets_dir = os.path.relpath(assets_dir, self._page.app.root_dir)
+        base_url = build_base_url(self._page.app, self._uri, rel_assets_dir)
         for fn in os.listdir(assets_dir):
             full_fn = os.path.join(assets_dir, fn)
             if not os.path.isfile(full_fn):
--- a/piecrust/environment.py	Tue Aug 19 12:48:00 2014 -0700
+++ b/piecrust/environment.py	Tue Aug 19 14:30:19 2014 -0700
@@ -73,7 +73,7 @@
         self.was_cache_cleaned = False
         self.page_repository = MemCache()
         self.rendered_segments_repository = MemCache()
-        self.base_asset_url_format = '%site_root%%uri%'
+        self.base_asset_url_format = '%uri%'
 
     def initialize(self, app):
         pass
--- a/tests/mockutil.py	Tue Aug 19 12:48:00 2014 -0700
+++ b/tests/mockutil.py	Tue Aug 19 14:30:19 2014 -0700
@@ -103,7 +103,7 @@
         contents = contents or "A test asset."
         url_base, ext = os.path.splitext(page_url)
         dirname = url_base + '-assets'
-        return self.withAsset('_content/pages/%s/%s' % (dirname, name),
+        return self.withAsset('_content/%s/%s' % (dirname, name),
                 contents)
 
 
--- a/tests/test_data_assetor.py	Tue Aug 19 12:48:00 2014 -0700
+++ b/tests/test_data_assetor.py	Tue Aug 19 14:30:19 2014 -0700
@@ -1,25 +1,27 @@
 import pytest
 from mock import MagicMock
-from piecrust.data.assetor import Assetor, UnsupportedAssetsError
+from piecrust.data.assetor import (Assetor, UnsupportedAssetsError,
+        build_base_url)
 from .mockutil import mock_fs, mock_fs_scope
 
 
 @pytest.mark.parametrize('fs, expected', [
-        (mock_fs().withPage('foo/bar'), {}),
+        (mock_fs().withPage('pages/foo/bar'), {}),
         (mock_fs()
-            .withPage('foo/bar')
-            .withPageAsset('foo/bar', 'one.txt', 'one'),
+            .withPage('pages/foo/bar')
+            .withPageAsset('pages/foo/bar', 'one.txt', 'one'),
             {'one': 'one'}),
         (mock_fs()
-            .withPage('foo/bar')
-            .withPageAsset('foo/bar', 'one.txt', 'one')
-            .withPageAsset('foo/bar', 'two.txt', 'two'),
+            .withPage('pages/foo/bar')
+            .withPageAsset('pages/foo/bar', 'one.txt', 'one')
+            .withPageAsset('pages/foo/bar', 'two.txt', 'two'),
             {'one': 'one', 'two': 'two'})
         ])
 def test_assets(fs, expected):
     with mock_fs_scope(fs):
         page = MagicMock()
         page.app = fs.getApp()
+        page.app.env.base_asset_url_format = '%uri%'
         page.path = fs.path('/kitchen/_content/pages/foo/bar.md')
         assetor = Assetor(page, '/foo/bar')
         for en in expected.keys():
@@ -31,7 +33,7 @@
 
 def test_missing_asset():
     with pytest.raises(KeyError):
-        fs = mock_fs().withPage('foo/bar')
+        fs = mock_fs().withPage('pages/foo/bar')
         with mock_fs_scope(fs):
             page = MagicMock()
             page.app = fs.getApp()
@@ -43,9 +45,9 @@
 def test_multiple_assets_with_same_name():
     with pytest.raises(UnsupportedAssetsError):
         fs = (mock_fs()
-                .withPage('foo/bar')
-                .withPageAsset('foo/bar', 'one.txt', 'one text')
-                .withPageAsset('foo/bar', 'one.jpg', 'one picture'))
+                .withPage('pages/foo/bar')
+                .withPageAsset('pages/foo/bar', 'one.txt', 'one text')
+                .withPageAsset('pages/foo/bar', 'one.jpg', 'one picture'))
         with mock_fs_scope(fs):
             page = MagicMock()
             page.app = fs.getApp()
@@ -53,3 +55,23 @@
             assetor = Assetor(page, '/foo/bar')
             assetor['one']
 
+
+@pytest.mark.parametrize('url_format, pretty_urls, uri, expected', [
+        ('%uri%', True, '/foo', '/foo/'),
+        ('%uri%', True, '/foo/2', '/foo/'),
+        ('%uri%', True, '/foo.ext', '/foo.ext/'),
+        ('%uri%', True, '/foo.ext/2', '/foo.ext/'),
+        ('%uri%', False, '/foo.html', '/foo/'),
+        ('%uri%', False, '/foo/2.html', '/foo/'),
+        ])
+def test_build_base_url(url_format, pretty_urls, uri, expected):
+    app = MagicMock()
+    app.env = MagicMock()
+    app.env.base_asset_url_format = url_format
+    app.config = {
+            'site/pretty_urls': pretty_urls,
+            '__cache/pagination_suffix_re': '/(?P<num>\\d+)$'}
+    assets_path = 'foo/bar-assets'
+    actual = build_base_url(app, uri, assets_path)
+    assert actual == expected
+