Pass positional arguments to attachment render functions

This allows handling `{attachment slug link}` as a synonym for
`{attachment slug link=self}`.
This commit is contained in:
Sybren A. Stüvel 2018-04-03 15:42:47 +02:00
parent a71de3a727
commit 1ba1da49c3
2 changed files with 68 additions and 9 deletions

View File

@ -194,7 +194,7 @@ class Attachment:
except self.NotSupported as ex: except self.NotSupported as ex:
return html_module.escape('{attachment %s}' % ex) return html_module.escape('{attachment %s}' % ex)
return self.render(file_doc, kwargs) return self.render(file_doc, pargs, kwargs)
def sdk_file(self, slug: str, node_properties: dict) -> pillarsdk.File: def sdk_file(self, slug: str, node_properties: dict) -> pillarsdk.File:
"""Return the file document for the attachment with this slug.""" """Return the file document for the attachment with this slug."""
@ -222,7 +222,9 @@ class Attachment:
sdk_file = pillarsdk.File.find(object_id, api=api) sdk_file = pillarsdk.File.find(object_id, api=api)
return sdk_file return sdk_file
def render(self, sdk_file: pillarsdk.File, tag_args: dict) -> str: def render(self, sdk_file: pillarsdk.File,
pargs: typing.List[str],
kwargs: typing.Dict[str, str]) -> str:
file_renderers = { file_renderers = {
'image': self.render_image, 'image': self.render_image,
'video': self.render_video, 'video': self.render_video,
@ -230,21 +232,29 @@ class Attachment:
mime_type_cat, _ = sdk_file.content_type.split('/', 1) mime_type_cat, _ = sdk_file.content_type.split('/', 1)
renderer = file_renderers.get(mime_type_cat, self.render_generic) renderer = file_renderers.get(mime_type_cat, self.render_generic)
return renderer(sdk_file, tag_args) return renderer(sdk_file, pargs, kwargs)
def render_generic(self, sdk_file, tag_args): def render_generic(self, sdk_file,
pargs: typing.List[str],
kwargs: typing.Dict[str, str]):
import flask import flask
return flask.render_template('nodes/attachments/file_generic.html', return flask.render_template('nodes/attachments/file_generic.html',
file=sdk_file, tag_args=tag_args) file=sdk_file, tag_args=kwargs)
def render_image(self, sdk_file, tag_args): def render_image(self, sdk_file,
pargs: typing.List[str],
kwargs: typing.Dict[str, str]):
"""Renders an image file.""" """Renders an image file."""
import flask import flask
if 'link' in pargs:
kwargs['link'] = 'self'
variations = {var.size: var for var in sdk_file.variations} variations = {var.size: var for var in sdk_file.variations}
return flask.render_template('nodes/attachments/file_image.html', return flask.render_template('nodes/attachments/file_image.html',
file=sdk_file, vars=variations, tag_args=tag_args) file=sdk_file, vars=variations, tag_args=kwargs)
def render_video(self, sdk_file, tag_args): def render_video(self, sdk_file,
pargs: typing.List[str],
kwargs: typing.Dict[str, str]):
"""Renders a video file.""" """Renders a video file."""
import flask import flask
try: try:
@ -255,7 +265,7 @@ class Attachment:
return flask.render_template('nodes/attachments/file_generic.html', file=sdk_file) return flask.render_template('nodes/attachments/file_generic.html', file=sdk_file)
return flask.render_template('nodes/attachments/file_video.html', return flask.render_template('nodes/attachments/file_video.html',
file=sdk_file, var=default_variation, tag_args=tag_args) file=sdk_file, var=default_variation, tag_args=kwargs)
def _get_parser() -> typing.Tuple[shortcodes.Parser, shortcodes.Parser]: def _get_parser() -> typing.Tuple[shortcodes.Parser, shortcodes.Parser]:

View File

@ -155,3 +155,52 @@ class IFrameTest(AbstractPillarTest):
with self.app.app_context(): with self.app.app_context():
self.login_api_as(uid, roles=roles) self.login_api_as(uid, roles=roles)
self.assertEqual(expect, render(md)) self.assertEqual(expect, render(md))
class AttachmentTest(AbstractPillarTest):
def test_image(self):
from pillar.shortcodes import render
oid, _ = self.ensure_file_exists(file_overrides={
'variations': [
{'format': 'jpg', 'height': 2048, 'width': 2048, 'length': 819569,
'link': 'https://i.imgur.com/FmbuPNe.jpg',
'content_type': 'image/jpeg',
'md5': '--',
'file_path': 'c2a5c897769ce1ef0eb10f8fa1c472bcb8e2d5a4-h.jpg',
'size': 'l'},
],
'filename': 'cute_kitten.jpg',
})
node_props = {
'attachments': {
'img': {'oid': oid},
}
}
# We have to get the file document again, because retrieving it via the
# API (which is what the shortcode rendering is doing) will change its
# link URL.
db_file = self.get(f'/api/files/{oid}').json()
link = db_file['variations'][0]['link']
with self.app.test_request_context():
self.assertEqual(
f'<a href="{link}"><img src="{link}" alt="cute_kitten.jpg"/></a>',
render('{attachment img link}', context=node_props).strip()
)
self.assertEqual(
f'<a href="{link}"><img src="{link}" alt="cute_kitten.jpg"/></a>',
render('{attachment img link=self}', context=node_props).strip()
)
self.assertEqual(
f'<img src="{link}" alt="cute_kitten.jpg"/>',
render('{attachment img}', context=node_props).strip()
)
tag_link = 'https://i.imgur.com/FmbuPNe.jpg'
self.assertEqual(
f'<a href="{tag_link}" target="_blank">'
f'<img src="{link}" alt="cute_kitten.jpg"/></a>',
render('{attachment img link=%r}' % tag_link, context=node_props).strip()
)