Skip to content
Browse files

* css url rewriting also works with absolute pats.

* added unit tests
* use urlparse rather than os.path
  • Loading branch information...
1 parent 88efa64 commit baffe75846b6b24b66f0eaad3b65712f7d74b151 @kux kux committed Dec 27, 2012
Showing with 112 additions and 9 deletions.
  1. +7 −9 filertags/signals.py
  2. BIN filertags/test_files/foobar.png
  3. +105 −0 filertags/tests.py
View
16 filertags/signals.py
@@ -29,7 +29,7 @@ def _is_in_clipboard(filer_file):
def _construct_logical_folder_path(filer_file):
- return os.path.join(*(folder.name for folder in filer_file.logical_path))
+ return '/%s/' % '/'.join((folder.name for folder in filer_file.logical_path))
def _get_commented_regions(content):
@@ -134,7 +134,7 @@ def resolve_resource_urls(instance, **kwargs):
in css files.
django-filer has two concepts of urls:
- * the logical url: media/images/foobar.png
+ * the logical url: /media/images/foobar.png
* the actual url: filer_public/2012/11/22/foobar.png
Example: the css as written by the an end user uses logical urls:
@@ -155,7 +155,7 @@ def resolve_resource_urls(instance, **kwargs):
After url rewriting the above css example will look like:
.button.nice {
- background: url('filer_public/2012/11/22/foobar.png') /* logicalurl('media/images/misc/foobar.png') /* ;
+ background: url('filer_public/2012/11/22/foobar.png') /* logicalurl('/media/images/misc/foobar.png') /* ;
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.5);
}
@@ -191,9 +191,7 @@ def change_urls(match):
# or explicitly specifies a hostname; these are resources
# not served from filer
return match.group()
- relative_path = url
- logical_file_path = os.path.normpath(
- os.path.join(logical_folder_path, relative_path))
+ logical_file_path = urlparse.urljoin(logical_folder_path, url)
if not logical_file_path in local_cache:
local_cache[logical_file_path] = _RESOURCE_URL_TEMPLATE % (
filerfile(logical_file_path), logical_file_path)
@@ -212,7 +210,7 @@ def update_referencing_css_files(instance, **kwargs):
reference the resource pointed by 'instance'.
References are found by parsing all css files and looking for comments such as:
- /* logicalurl('media/images/misc/foobar.png') */
+ /* logicalurl('/media/images/misc/foobar.png') */
If the url between parentheses matches the logical url of the resource
being saved, the actual url (which percedes the comment)
@@ -224,7 +222,7 @@ def update_referencing_css_files(instance, **kwargs):
if _is_in_clipboard(resource_file):
return
resource_name = _get_filer_file_name(resource_file)
- logical_file_path = os.path.join(
+ logical_file_path = urlparse.urljoin(
_construct_logical_folder_path(resource_file),
resource_name)
css_files = File.objects.filter(original_filename__endswith=".css")
@@ -252,7 +250,7 @@ def update_referencing_css_files(instance, **kwargs):
def clear_urls_cache(instance, **kwargs):
"""Clears urls cached by the filerfile tag. """
- logical_file_path = os.path.join(
+ logical_file_path = urlparse.urljoin(
_construct_logical_folder_path(instance),
instance.original_filename)
cache_key = get_filerfile_cache_key(logical_file_path)
View
BIN filertags/test_files/foobar.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
105 filertags/tests.py
@@ -0,0 +1,105 @@
+import os.path
+import re
+
+from django.core.cache import cache
+from django.core.files.base import File as DjangoFile, ContentFile
+from django.test import TestCase
+
+from filer.models.filemodels import File
+from filer.models.foldermodels import Folder
+from filer.tests.helpers import (create_superuser, create_folder_structure,
+ create_image, create_clipboard_item)
+
+from filertags.signals import _ALREADY_PARSED_MARKER, _LOGICAL_URL_TEMPLATE
+
+
+class CssRewriteTest(TestCase):
+
+ def setUp(self):
+ self.superuser = create_superuser()
+ self.client.login(username='admin', password='secret')
+ media_folder = Folder.objects.create(name='media')
+ producer = Folder.objects.create(name='producer', parent=media_folder)
+ self.producer_css = Folder.objects.create(name='css', parent=producer)
+ self.producer_images = Folder.objects.create(name='images', parent=producer)
+
+ def tearDown(self):
+ cache.clear()
+
+ def create_file(self, name, folder, content=None):
+ if content is None:
+ file_obj = DjangoFile(
+ open(os.path.join(os.path.dirname(__file__), 'test_files', name)),
+ name=name)
+ else:
+ file_obj = ContentFile(content, name)
+ return File.objects.create(owner=self.superuser,
+ original_filename=name,
+ file=file_obj,
+ folder=folder)
+
+
+ def test_abslute_url_css_before_image(self):
+ css = self.create_file('absolute_url_to_image.css', self.producer_css,
+ content="""\
+.pledge-block {
+ background: url('/media/producer/images/foobar.png');
+}
+""")
+ css_content = open(css.path).read()
+ self.assertTrue(css_content.startswith(_ALREADY_PARSED_MARKER))
+ self.assertIn("url('')", css_content)
+ logical_url = _LOGICAL_URL_TEMPLATE % '/media/producer/images/foobar.png'
+ self.assertIn(logical_url, css_content)
+ image = self.create_file('foobar.png', self.producer_images)
+ updated_css = File.objects.get(pk=css.pk)
+ new_content = open(updated_css.path).read()
+ self.assertIsNotNone(re.search(r"\burl\('[^']*foobar[^']*png'\)", new_content))
+
+ def _verify_css_is_corectly_rewritten(self, css):
+ css_content = open(css.path).read()
+ self.assertTrue(css_content.startswith(_ALREADY_PARSED_MARKER))
+ logical_url = _LOGICAL_URL_TEMPLATE % '/media/producer/images/foobar.png'
+ self.assertIn(logical_url, css_content)
+ self.assertIsNotNone(re.search(r"\burl\('[^']*foobar[^']*png'\)", css_content))
+
+ def test_abslute_url_image_before_css(self):
+ image = self.create_file('foobar.png', self.producer_images)
+ css = self.create_file('absolute_url_to_image.css', self.producer_css,
+ content="""\
+.pledge-block {
+ background: url('/media/producer/images/foobar.png');
+}
+""")
+ self._verify_css_is_corectly_rewritten(css)
+
+ def test_relative_url_image_before_css(self):
+ image = self.create_file('foobar.png', self.producer_images)
+ css = self.create_file('relative_url_to_image.css', self.producer_css,
+ content="""\
+.pledge-block {
+ background: url('../images/foobar.png');
+}
+""")
+ self._verify_css_is_corectly_rewritten(css)
+
+ def test_double_quoted_url(self):
+ image = self.create_file('foobar.png', self.producer_images)
+ css = self.create_file('relative_url_to_image.css', self.producer_css,
+ content="""\
+.pledge-block {
+ background: url( " ../images/foobar.png " );
+}
+""")
+ self._verify_css_is_corectly_rewritten(css)
+
+ def test_unquoted_url(self):
+ image = self.create_file('foobar.png', self.producer_images)
+ css = self.create_file('relative_url_to_image.css', self.producer_css,
+ content="""\
+.pledge-block {
+ background: url( ../images/foobar.png );
+}
+""")
+ self._verify_css_is_corectly_rewritten(css)
+

0 comments on commit baffe75

Please sign in to comment.
Something went wrong with that request. Please try again.