Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 277 lines (244 sloc) 9.688 kB
de01157 A bit of pychecker cleanup.
Batiste Bieler authored
1 """Placeholder module, that's where the smart things appened."""
2
3 from pages.widgets_registry import get_widget
4 from pages import settings
5 from pages.models import Content
6 from pages.widgets import ImageInput, VideoWidget
7
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
8 from django import template
9 from django.template import Template, TemplateSyntaxError
10 from django.core.files.storage import FileSystemStorage
de01157 A bit of pychecker cleanup.
Batiste Bieler authored
11 from django.forms import Textarea, ImageField, CharField
caed26c Add a widget regitery to register new widgets for the placeholders.
Batiste Bieler authored
12 from django.forms import TextInput
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
13 from django.conf import settings as global_settings
14 from django.utils.translation import ugettext_lazy as _
de01157 A bit of pychecker cleanup.
Batiste Bieler authored
15 from django.utils.safestring import mark_safe
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
16 from django.template.loader import render_to_string
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
17
18 import os
19 import time
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
20 import re
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
21
de01157 A bit of pychecker cleanup.
Batiste Bieler authored
22 PLACEHOLDER_ERROR = _("[Placeholder %(name)s had syntax error: %(error)s]")
23
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
24 def parse_placeholder(parser, token):
fff698b Documentation and cleanup
Batiste Bieler authored
25 """Parse the `PlaceholderNode` parameters.
26
27 Return a tuple with the name and parameters."""
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
28 bits = token.split_contents()
29 count = len(bits)
30 error_string = '%r tag requires at least one argument' % bits[0]
31 if count <= 1:
6d85fbf Test various template syntax errors.
Batiste Bieler authored
32 raise TemplateSyntaxError(error_string)
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
33 name = bits[1]
34 remaining = bits[2:]
35 params = {}
6d1ec55 Make the untranslated synta to work.
Batiste Bieler authored
36 simple_options = ['parsed', 'inherited', 'untranslated']
37 param_options = ['as', 'on', 'with']
38 all_options = simple_options + param_options
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
39 while remaining:
40 bit = remaining[0]
6d1ec55 Make the untranslated synta to work.
Batiste Bieler authored
41 if bit not in all_options:
6d85fbf Test various template syntax errors.
Batiste Bieler authored
42 raise TemplateSyntaxError(
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
43 "%r is not an correct option for a placeholder" % bit)
6d1ec55 Make the untranslated synta to work.
Batiste Bieler authored
44 if bit in param_options:
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
45 if len(remaining) < 2:
6d85fbf Test various template syntax errors.
Batiste Bieler authored
46 raise TemplateSyntaxError(
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
47 "Placeholder option '%s' need a parameter" % bit)
48 if bit == 'as':
49 params['as_varname'] = remaining[1]
50 if bit == 'with':
51 params['widget'] = remaining[1]
52 if bit == 'on':
53 params['page'] = remaining[1]
54 remaining = remaining[2:]
7757a1f Add an inheritance for placeholder content.
Batiste Bieler authored
55 elif bit == 'parsed':
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
56 params['parsed'] = True
57 remaining = remaining[1:]
7757a1f Add an inheritance for placeholder content.
Batiste Bieler authored
58 elif bit == 'inherited':
59 params['inherited'] = True
60 remaining = remaining[1:]
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
61 elif bit == 'untranslated':
62 params['untranslated'] = True
63 remaining = remaining[1:]
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
64 return name, params
65
66
67 class PlaceholderNode(template.Node):
68 """This template node is used to output page content and
69 dynamically generate input fields in the admin.
70
71 :param name: the name of the placeholder you want to show/create
72 :param page: the optional page object
73 :param widget: the widget you want to use in the admin interface. Take
0e5f91e Move widget out of the admin
Batiste Bieler authored
74 a look into :mod:`pages.widgets` to see which widgets
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
75 are available.
76 :param parsed: if the ``parsed`` word is given, the content of the
fff698b Documentation and cleanup
Batiste Bieler authored
77 placeholder is evaluated as template code, within the current
78 context.
79 :param as_varname: if ``as_varname`` is defined, no value will be
80 returned. A variable will be created in the context
81 with the defined name.
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
82 :param inherited: inherit content from parent's pages.
83 :param untranslated: the placeholder's content is the same for
84 every language.
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
85 """
86
87 field = CharField
d12e64b Now you can choose the width and height in the youtube video placehol…
Batiste Bieler authored
88 widget = TextInput
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
89
d12e64b Now you can choose the width and height in the youtube video placehol…
Batiste Bieler authored
90 def __init__(self, name, page=None, widget=None, parsed=False,
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
91 as_varname=None, inherited=False, untranslated=False):
92 """Gather parameters for the `PlaceholderNode`.
fff698b Documentation and cleanup
Batiste Bieler authored
93
94 These values should be thread safe and don't change between calls."""
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
95 self.page = page or 'current_page'
96 self.name = name
d12e64b Now you can choose the width and height in the youtube video placehol…
Batiste Bieler authored
97 if widget:
98 self.widget = widget
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
99 self.parsed = parsed
7757a1f Add an inheritance for placeholder content.
Batiste Bieler authored
100 self.inherited = inherited
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
101 self.untranslated = untranslated
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
102 self.as_varname = as_varname
103 self.found_in_block = None
104
105 def get_widget(self, page, language, fallback=Textarea):
fff698b Documentation and cleanup
Batiste Bieler authored
106 """Given the name of a placeholder return a `Widget` subclass
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
107 like Textarea or TextInput."""
caed26c Add a widget regitery to register new widgets for the placeholders.
Batiste Bieler authored
108 is_str = type(self.widget) == type(str())
009596d Use urlconf module to delegate everything.
Batiste Bieler authored
109 is_unicode = type(self.widget) == type(unicode())
caed26c Add a widget regitery to register new widgets for the placeholders.
Batiste Bieler authored
110 if is_str or is_unicode:
111 widget = get_widget(self.widget)
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
112 else:
caed26c Add a widget regitery to register new widgets for the placeholders.
Batiste Bieler authored
113 widget = self.widget
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
114 try:
caed26c Add a widget regitery to register new widgets for the placeholders.
Batiste Bieler authored
115 return widget(page=page, language=language)
116 except:
117 pass
118 return widget()
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
119
120 def get_field(self, page, language, initial=None):
2526510 @batiste Improve the documentation
batiste authored
121 """The field that will be shown within the admin."""
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
122 if self.parsed:
123 help_text = _('Note: This field is evaluated as template code.')
124 else:
fff698b Documentation and cleanup
Batiste Bieler authored
125 help_text = ''
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
126 widget = self.get_widget(page, language)
127 return self.field(widget=widget, initial=initial,
128 help_text=help_text, required=False)
129
130 def save(self, page, language, data, change):
2526510 @batiste Improve the documentation
batiste authored
131 """Actually save the placeholder data into the Content object."""
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
132 # if this placeholder is untranslated, we save everything
133 # in the default language
134 if self.untranslated:
135 language = settings.PAGE_DEFAULT_LANGUAGE
136
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
137 # the page is being changed
138 if change:
139 # we need create a new content if revision is enabled
140 if(settings.PAGE_CONTENT_REVISION and self.name
141 not in settings.PAGE_CONTENT_REVISION_EXCLUDE_LIST):
142 Content.objects.create_content_if_changed(
143 page,
144 language,
145 self.name,
146 data
147 )
148 else:
149 Content.objects.set_or_create_content(
150 page,
151 language,
152 self.name,
153 data
154 )
155 # the page is being added
156 else:
157 Content.objects.set_or_create_content(
158 page,
159 language,
160 self.name,
161 data
162 )
163
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
164 def get_content(self, page_obj, lang, lang_fallback=True):
165 content = Content.objects.get_content(page_obj, lang, self.name,
166 lang_fallback)
3d33030 Re enable the hierarchy rights management. Little optimization on inh…
Batiste Bieler authored
167 if self.inherited and not content:
168 for ancestor in page_obj.get_ancestors():
169 content = Content.objects.get_content(ancestor, lang,
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
170 self.name, lang_fallback)
3d33030 Re enable the hierarchy rights management. Little optimization on inh…
Batiste Bieler authored
171 if content:
172 break
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
173 return content
174
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
175 def get_content_from_context(self, context):
176 if not self.page in context:
177 return ''
178 # current_page can be set to None
179 if not context[self.page]:
180 return ''
181
182 if self.untranslated:
183 lang_fallback = False
184 lang = settings.PAGE_DEFAULT_LANGUAGE
185 else:
186 lang_fallback = True
187 lang = context.get('lang', settings.PAGE_DEFAULT_LANGUAGE)
188 return self.get_content(context[self.page], lang, lang_fallback)
189
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
190 def render(self, context):
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
191 """Output the content of the `PlaceholdeNode` in the template."""
192
193 content = self.get_content_from_context(context)
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
194 if not content:
195 return ''
196 if self.parsed:
197 try:
198 t = template.Template(content, name=self.name)
199 content = mark_safe(t.render(context))
6d85fbf Test various template syntax errors.
Batiste Bieler authored
200 except TemplateSyntaxError, error:
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
201 if global_settings.DEBUG:
6d85fbf Test various template syntax errors.
Batiste Bieler authored
202 content = PLACEHOLDER_ERROR % {
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
203 'name': self.name,
204 'error': error,
205 }
206 else:
6d85fbf Test various template syntax errors.
Batiste Bieler authored
207 content = ''
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
208 if self.as_varname is None:
209 return content
210 context[self.as_varname] = content
211 return ''
212
213 def __repr__(self):
214 return "<Placeholder Node: %s>" % self.name
215
216
217 class ImagePlaceholderNode(PlaceholderNode):
fff698b Documentation and cleanup
Batiste Bieler authored
218 """A `PlaceholderNode` that saves one image on disk.
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
219
fff698b Documentation and cleanup
Batiste Bieler authored
220 `PAGE_UPLOAD_ROOT` setting define where to save the image.
221 """
caed26c Add a widget regitery to register new widgets for the placeholders.
Batiste Bieler authored
222
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
223 def get_field(self, page, language, initial=None):
224 help_text = ""
009596d Use urlconf module to delegate everything.
Batiste Bieler authored
225 widget = ImageInput(page, language)
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
226 return ImageField(
227 widget=widget,
228 initial=initial,
229 help_text=help_text,
230 required=False
231 )
232
233 def save(self, page, language, data, change):
234 filename = ""
d12e64b Now you can choose the width and height in the youtube video placehol…
Batiste Bieler authored
235 if change and data:
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
236 storage = FileSystemStorage()
fff698b Documentation and cleanup
Batiste Bieler authored
237 filename = os.path.join(
238 settings.PAGE_UPLOAD_ROOT,
239 'page_'+str(page.id),
240 self.name + '-' + str(time.time())
241 )
8726b8a Keep filename extension on imageplaceholder uploads
johannes authored
242
f9484d5 Ensure lower cased file extensions and allow 4 charachters on uploade…
johannes authored
243 m = re.search('\.[a-zA-Z]{1,4}$', str(data))
8726b8a Keep filename extension on imageplaceholder uploads
johannes authored
244 if m is not None:
f9484d5 Ensure lower cased file extensions and allow 4 charachters on uploade…
johannes authored
245 filename += m.group(0).lower()
8726b8a Keep filename extension on imageplaceholder uploads
johannes authored
246
c05f18f @batiste Make the image placeholder tag to work properly. Refactor the code at…
batiste authored
247 filename = storage.save(filename, data)
248 super(ImagePlaceholderNode, self).save(
249 page,
250 language,
251 filename,
252 change
253 )
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
254
255 class VideoPlaceholderNode(PlaceholderNode):
d12e64b Now you can choose the width and height in the youtube video placehol…
Batiste Bieler authored
256 """A youtube `PlaceholderNode`, just here as an example."""
257
258 widget = VideoWidget
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
259
260 def render(self, context):
3fd79ba Add the untranslated placeholder keyword. Enable the user to have a s…
Batiste Bieler authored
261 content = self.get_content_from_context(context)
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
262 if not content:
263 return ''
264 if content:
d12e64b Now you can choose the width and height in the youtube video placehol…
Batiste Bieler authored
265 video_url, w, h = content.split('\\')
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
266 m = re.search('youtube\.com\/watch\?v=([^&]+)', content)
267 if m:
268 video_url = 'http://www.youtube.com/v/'+m.group(1)
d12e64b Now you can choose the width and height in the youtube video placehol…
Batiste Bieler authored
269 if not w:
270 w = 425
271 if not h:
272 h = 344
273 context = {'video_url': video_url, 'w':w, 'h':h}
b77bf4a Add a video placeholder tag example
Batiste Bieler authored
274 renderer = render_to_string('pages/embed.html', context)
275 return mark_safe(renderer)
276 return ''
Something went wrong with that request. Please try again.