| @@ -1,3 +1,9 @@ | |||||
| Version 0.8.5a1 | |||||
| ============================================================ | |||||
| * Added ability to specify safe characters in `content_url`, | |||||
| `media_url` functions and `urlencode` filter. (Issue #103) | |||||
| Version 0.8.4 | Version 0.8.4 | ||||
| ============================================================ | ============================================================ | ||||
| @@ -1,4 +1,4 @@ | |||||
| Version 0.8.4 | |||||
| Version 0.8.5a1 | |||||
| A brand new **hyde** | A brand new **hyde** | ||||
| ==================== | ==================== | ||||
| @@ -53,8 +53,8 @@ class UrlCleanerPlugin(Plugin): | |||||
| def clean_url(urlgetter): | def clean_url(urlgetter): | ||||
| @wraps(urlgetter) | @wraps(urlgetter) | ||||
| def wrapper(site, path): | |||||
| url = urlgetter(site, path) | |||||
| def wrapper(site, path, safe=None): | |||||
| url = urlgetter(site, path, safe) | |||||
| index_file_names = getattr(settings, | index_file_names = getattr(settings, | ||||
| 'index_file_names', | 'index_file_names', | ||||
| ['index.html']) | ['index.html']) | ||||
| @@ -36,29 +36,32 @@ class SilentUndefined(Undefined): | |||||
| return self | return self | ||||
| @contextfunction | @contextfunction | ||||
| def media_url(context, path): | |||||
| def media_url(context, path, safe=None): | |||||
| """ | """ | ||||
| Returns the media url given a partial path. | Returns the media url given a partial path. | ||||
| """ | """ | ||||
| return context['site'].media_url(path) | |||||
| return context['site'].media_url(path, safe) | |||||
| @contextfunction | @contextfunction | ||||
| def content_url(context, path): | |||||
| def content_url(context, path, safe=None): | |||||
| """ | """ | ||||
| Returns the content url given a partial path. | Returns the content url given a partial path. | ||||
| """ | """ | ||||
| return context['site'].content_url(path) | |||||
| return context['site'].content_url(path, safe) | |||||
| @contextfunction | @contextfunction | ||||
| def full_url(context, path): | |||||
| def full_url(context, path, safe=None): | |||||
| """ | """ | ||||
| Returns the full url given a partial path. | Returns the full url given a partial path. | ||||
| """ | """ | ||||
| return context['site'].full_url(path) | |||||
| return context['site'].full_url(path, safe) | |||||
| @contextfilter | @contextfilter | ||||
| def urlencode(ctx, url): | |||||
| return quote(url.encode('utf8')) | |||||
| def urlencode(ctx, url, safe=None): | |||||
| if safe is not None: | |||||
| return quote(url.encode('utf8'), safe) | |||||
| else: | |||||
| return quote(url.encode('utf8')) | |||||
| @contextfilter | @contextfilter | ||||
| def urldecode(ctx, url): | def urldecode(ctx, url): | ||||
| @@ -51,7 +51,6 @@ class Processable(object): | |||||
| """ | """ | ||||
| return self.source.path | return self.source.path | ||||
| class Resource(Processable): | class Resource(Processable): | ||||
| """ | """ | ||||
| Represents any file that is processed by hyde | Represents any file that is processed by hyde | ||||
| @@ -412,33 +411,46 @@ class Site(object): | |||||
| """ | """ | ||||
| self.content.load() | self.content.load() | ||||
| def content_url(self, path): | |||||
| def content_url(self, path, safe=None): | |||||
| """ | """ | ||||
| Returns the content url by appending the base url from the config | Returns the content url by appending the base url from the config | ||||
| with the given path. | |||||
| with the given path. The return value is url encoded. | |||||
| """ | """ | ||||
| return quote(Folder(self.config.base_url).child(path).replace(os.sep, '/').encode("utf-8")) | |||||
| fpath = Folder(self.config.base_url) \ | |||||
| .child(path) \ | |||||
| .replace(os.sep, '/').encode("utf-8") | |||||
| if safe is not None: | |||||
| return quote(fpath, safe) | |||||
| else: | |||||
| return quote(fpath) | |||||
| def media_url(self, path): | |||||
| def media_url(self, path, safe=None): | |||||
| """ | """ | ||||
| Returns the media url by appending the media base url from the config | Returns the media url by appending the media base url from the config | ||||
| with the given path. | |||||
| with the given path. The return value is url encoded. | |||||
| """ | """ | ||||
| return quote(Folder(self.config.media_url).child(path).replace(os.sep, '/').encode("utf-8")) | |||||
| fpath = Folder(self.config.media_url) \ | |||||
| .child(path) \ | |||||
| .replace(os.sep, '/').encode("utf-8") | |||||
| if safe is not None: | |||||
| return quote(fpath, safe) | |||||
| else: | |||||
| return quote(fpath) | |||||
| def full_url(self, path): | |||||
| def full_url(self, path, safe=None): | |||||
| """ | """ | ||||
| Determines if the given path is media or content based on the | Determines if the given path is media or content based on the | ||||
| configuration and returns the appropriate url. | |||||
| configuration and returns the appropriate url. The return value | |||||
| is url encoded. | |||||
| """ | """ | ||||
| if urlparse.urlparse(path)[:2] != ("",""): | if urlparse.urlparse(path)[:2] != ("",""): | ||||
| return path | return path | ||||
| if self.is_media(path): | if self.is_media(path): | ||||
| relative_path = File(path).get_relative_path( | relative_path = File(path).get_relative_path( | ||||
| Folder(self.config.media_root)) | Folder(self.config.media_root)) | ||||
| return self.media_url(relative_path) | |||||
| return self.media_url(relative_path, safe) | |||||
| else: | else: | ||||
| return self.content_url(path) | |||||
| return self.content_url(path, safe) | |||||
| def is_media(self, path): | def is_media(self, path): | ||||
| """ | """ | ||||
| @@ -197,6 +197,18 @@ class TestSiteWithConfig(object): | |||||
| path = 'blog/2010/december' | path = 'blog/2010/december' | ||||
| assert s.content_url(path) == "/" + path | assert s.content_url(path) == "/" + path | ||||
| def test_content_url_encoding(self): | |||||
| s = Site(self.SITE_PATH, config=self.config) | |||||
| s.load() | |||||
| path = '".jpg' | |||||
| assert s.content_url(path) == quote("/" + path) | |||||
| def test_content_url_encoding_safe(self): | |||||
| s = Site(self.SITE_PATH, config=self.config) | |||||
| s.load() | |||||
| path = '".jpg/abc' | |||||
| assert s.content_url(path, "") == quote("/" + path, "") | |||||
| def test_media_url(self): | def test_media_url(self): | ||||
| s = Site(self.SITE_PATH, config=self.config) | s = Site(self.SITE_PATH, config=self.config) | ||||
| s.load() | s.load() | ||||
| @@ -3,4 +3,4 @@ | |||||
| Handles hyde version | Handles hyde version | ||||
| TODO: Use fabric like versioning scheme | TODO: Use fabric like versioning scheme | ||||
| """ | """ | ||||
| __version__ = '0.8.4' | |||||
| __version__ = '0.8.5a1' | |||||