Spec templatetag returns html by default

...if no 'as var' is provided or if the var is printed directly.
This commit is contained in:
Eric Eldredge 2012-09-06 15:29:57 -04:00
parent bdecf75e0a
commit ec9a1f1fda
2 changed files with 46 additions and 24 deletions

View file

@ -3,7 +3,7 @@ import os
from django.db.models.fields.files import ImageFieldFile
from .generators import SpecFileGenerator
from .utils import SpecWrapper
from .utils import SpecWrapper, suggest_extension
class ImageSpecFile(ImageFieldFile):
@ -44,7 +44,7 @@ class ImageSpecFile(ImageFieldFile):
source_filename = self.source_file.name
filepath, basename = os.path.split(source_filename)
filename = os.path.splitext(basename)[0]
extension = self.generator.suggest_extension(source_filename)
extension = suggest_extension(source_filename, self.generator.format)
new_name = '%s%s' % (filename, extension)
cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \
[filepath, new_name]

View file

@ -1,5 +1,6 @@
import os
from django import template
from django.utils.safestring import mark_safe
from ..files import ImageSpecFile
@ -40,42 +41,55 @@ class SpecRegistry(object):
spec_registry = SpecRegistry()
class ImageSpecFileHtmlWrapper(object):
def __init__(self, image_spec_file):
self._image_spec_file = image_spec_file
def __getattr__(self, name):
return getattr(self._image_spec_file, name)
def __unicode__(self):
return mark_safe(u'<img src="%s" />' % self.url)
class SpecNode(template.Node):
def __init__(self, spec_id, source_image, variable_name):
def __init__(self, spec_id, source_image, variable_name=None):
self.spec_id = spec_id
self.source_image = source_image
self.variable_name = variable_name
def _default_cache_to(self, instance, path, specname, extension):
"""
Determines the filename to use for the transformed image. Can be
overridden on a per-spec basis by setting the cache_to property on
the spec.
"""
filepath, basename = os.path.split(path)
filename = os.path.splitext(basename)[0]
new_name = '%s_%s%s' % (filename, specname, extension)
return os.path.join(os.path.join('cache', filepath), new_name)
def render(self, context):
from ..utils import autodiscover
autodiscover()
source_image = self.source_image.resolve(context)
variable_name = str(self.variable_name)
spec_id = self.spec_id.resolve(context)
spec = spec_registry.get_spec(spec_id)
if callable(spec):
spec = spec()
context[variable_name] = ImageSpecFile(spec, source_image, spec_id)
return ''
spec_file = ImageSpecFileHtmlWrapper(ImageSpecFile(spec, source_image, spec_id))
if self.variable_name is not None:
variable_name = str(self.variable_name)
context[variable_name] = spec_file
return ''
return spec_file
#@register.tag
# TODO: Should this be renamed to something like 'process'?
def spec(parser, token):
"""
Creates an image based on the provided spec and source image and sets it
as a context variable:
Creates an image based on the provided spec and source image.
By default::
{% spec 'myapp:thumbnail', mymodel.profile_image %}
Generates an ``<img>``::
<img src="/cache/34d944f200dd794bf1e6a7f37849f72b.jpg" />
Storing it as a context variable allows more flexibility::
{% spec 'myapp:thumbnail' mymodel.profile_image as th %}
<img src="{{ th.url }}" width="{{ th.width }}" height="{{ th.height }}" />
@ -83,12 +97,20 @@ def spec(parser, token):
"""
args = token.split_contents()
arg_count = len(args)
if len(args) != 5 or args[3] != 'as':
raise TemplateSyntaxError('\'spec\' tags must be in the form "{% spec spec_id image as varname %}"')
if (arg_count < 3 or arg_count > 5
or (arg_count > 3 and arg_count < 5)
or (args == 5 and args[3] != 'as')):
raise template.TemplateSyntaxError('\'spec\' tags must be in the form'
' "{% spec spec_id image %}" or'
' "{% spec spec_id image'
' as varname %}"')
return SpecNode(*[parser.compile_filter(arg) for arg in args[1:3] \
+ [args[4]]])
spec_id = parser.compile_filter(args[1])
source_image = parser.compile_filter(args[2])
variable_name = arg_count > 3 and args[4] or None
return SpecNode(spec_id, source_image, variable_name)
spec = spec_tag = register.tag(spec)