def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): """ Converts any URLs in text into clickable links. Works on http://, https://, www. links and links ending in .org, .net or .com. Links can have trailing punctuation (periods, commas, close-parens) and leading punctuation (opening parens) and it'll still do the right thing. If trim_url_limit is not None, the URLs in link text longer than this limit will truncated to trim_url_limit-3 characters and appended with an elipsis. If nofollow is True, the URLs in link text will get a rel="nofollow" attribute. If autoescape is True, the link text and URLs will get autoescaped. """ trim_url = lambda x, limit=trim_url_limit: limit is not None and (len( x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x safe_input = isinstance(text, SafeData) words = word_split_re.split(force_unicode(text)) nofollow_attr = nofollow and ' rel="nofollow"' or '' for i, word in enumerate(words): match = None if '.' in word or '@' in word or ':' in word: match = punctuation_re.match(word) if match: lead, middle, trail = match.groups() # Make URL we want to point to. url = None if middle.startswith('http://') or middle.startswith('https://'): url = urlquote(middle, safe='/&=:;#?+*') elif middle.startswith('www.') or ('@' not in middle and \ middle and middle[0] in string.ascii_letters + string.digits and \ (middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))): url = urlquote('http://%s' % middle, safe='/&=:;#?+*') elif '@' in middle and not ':' in middle and simple_email_re.match( middle): url = 'mailto:%s' % middle nofollow_attr = '' # Make link. if url: trimmed = trim_url(middle) if autoescape and not safe_input: lead, trail = escape(lead), escape(trail) url, trimmed = escape(url), escape(trimmed) middle = '<a href="%s"%s>%s</a>' % (url, nofollow_attr, trimmed) words[i] = mark_safe('%s%s%s' % (lead, middle, trail)) else: if safe_input: words[i] = mark_safe(word) elif autoescape: words[i] = escape(word) elif safe_input: words[i] = mark_safe(word) elif autoescape: words[i] = escape(word) return u''.join(words)
def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): """ Converts any URLs in text into clickable links. Works on http://, https://, www. links and links ending in .org, .net or .com. Links can have trailing punctuation (periods, commas, close-parens) and leading punctuation (opening parens) and it'll still do the right thing. If trim_url_limit is not None, the URLs in link text longer than this limit will truncated to trim_url_limit-3 characters and appended with an elipsis. If nofollow is True, the URLs in link text will get a rel="nofollow" attribute. If autoescape is True, the link text and URLs will get autoescaped. """ trim_url = lambda x, limit=trim_url_limit: limit is not None and (len(x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x safe_input = isinstance(text, SafeData) words = word_split_re.split(force_unicode(text)) nofollow_attr = nofollow and ' rel="nofollow"' or '' for i, word in enumerate(words): match = None if '.' in word or '@' in word or ':' in word: match = punctuation_re.match(word) if match: lead, middle, trail = match.groups() # Make URL we want to point to. url = None if middle.startswith('http://') or middle.startswith('https://'): url = urlquote(middle, safe='/&=:;#?+*') elif middle.startswith('www.') or ('@' not in middle and \ middle and middle[0] in string.ascii_letters + string.digits and \ (middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))): url = urlquote('http://%s' % middle, safe='/&=:;#?+*') elif '@' in middle and not ':' in middle and simple_email_re.match(middle): url = 'mailto:%s' % middle nofollow_attr = '' # Make link. if url: trimmed = trim_url(middle) if autoescape and not safe_input: lead, trail = escape(lead), escape(trail) url, trimmed = escape(url), escape(trimmed) middle = '<a href="%s"%s>%s</a>' % (url, nofollow_attr, trimmed) words[i] = mark_safe('%s%s%s' % (lead, middle, trail)) else: if safe_input: words[i] = mark_safe(word) elif autoescape: words[i] = escape(word) elif safe_input: words[i] = mark_safe(word) elif autoescape: words[i] = escape(word) return u''.join(words)
def render(self, name, value, attrs=None): substitutions = { 'initial_text': self.initial_text, 'input_text': self.input_text, 'clear_template': '', 'clear_checkbox_label': self.clear_checkbox_label, } template = u'%(input)s' substitutions['input'] = super(ClearableFileInput, self).render(name, value, attrs) if value and hasattr(value, "url"): template = self.template_with_initial substitutions['initial'] = ( u'<a href="%s">%s</a>' % (escape(value.url), escape(force_unicode(value)))) if not self.is_required: checkbox_name = self.clear_checkbox_name(name) checkbox_id = self.clear_checkbox_id(checkbox_name) substitutions['clear_checkbox_name'] = conditional_escape( checkbox_name) substitutions['clear_checkbox_id'] = conditional_escape( checkbox_id) substitutions['clear'] = CheckboxInput().render( checkbox_name, False, attrs={'id': checkbox_id}) substitutions[ 'clear_template'] = self.template_with_clear % substitutions return mark_safe(template % substitutions)
def as_table(self): "Returns this formset rendered as HTML <tr>s -- excluding the <table></table>." # XXX: there is no semantic division between forms here, there # probably should be. It might make sense to render each form as a # table row with each field as a td. forms = u' '.join([form.as_table() for form in self]) return mark_safe(u'\n'.join([unicode(self.management_form), forms]))
def escape(html): """ Returns the given HTML with ampersands, quotes and angle brackets encoded. """ return mark_safe( force_unicode(html).replace('&', '&').replace('<', '<').replace( '>', '>').replace('"', '"').replace("'", '''))
def tag(self): if 'id' in self.attrs: self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index) final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value) if self.is_checked(): final_attrs['checked'] = 'checked' return mark_safe(u'<input%s />' % flatatt(final_attrs))
def __unicode__(self): if 'id' in self.attrs: label_for = ' for="%s_%s"' % (self.attrs['id'], self.index) else: label_for = '' choice_label = conditional_escape(force_unicode(self.choice_label)) return mark_safe(u'<label%s>%s %s</label>' % (label_for, self.tag(), choice_label))
def render(self, name, value, attrs=None, choices=()): if value is None: value = [] has_id = attrs and 'id' in attrs final_attrs = self.build_attrs(attrs, name=name) output = [u'<ul>'] # Normalize to strings str_values = set([force_unicode(v) for v in value]) for i, (option_value, option_label) in enumerate(chain(self.choices, choices)): # If an ID attribute was given, add a numeric index as a suffix, # so that the checkboxes don't all have the same ID attribute. if has_id: final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i)) label_for = u' for="%s"' % final_attrs['id'] else: label_for = '' cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) option_value = force_unicode(option_value) rendered_cb = cb.render(name, option_value) option_label = conditional_escape(force_unicode(option_label)) output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label)) output.append(u'</ul>') return mark_safe(u'\n'.join(output))
def render(self, name, value, attrs=None): if value is None: value = '' final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) if value != '': # Only add the 'value' attribute if a value is non-empty. final_attrs['value'] = force_unicode(self._format_value(value)) return mark_safe(u'<input%s />' % flatatt(final_attrs))
def render(self, name, value, attrs=None, choices=()): if value is None: value = [] final_attrs = self.build_attrs(attrs, name=name) output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)] options = self.render_options(choices, value) if options: output.append(options) output.append('</select>') return mark_safe(u'\n'.join(output))
def render(self, name, value, attrs=None): final_attrs = self.build_attrs(attrs, type='checkbox', name=name) try: result = self.check_test(value) except: # Silently catch exceptions result = False if result: final_attrs['checked'] = 'checked' if value not in ('', True, False, None): # Only add the 'value' attribute if a value is non-empty. final_attrs['value'] = force_unicode(value) return mark_safe(u'<input%s />' % flatatt(final_attrs))
def render(self, name, value, attrs=None, choices=()): if value is None: value = [] final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) id_ = final_attrs.get('id', None) inputs = [] for i, v in enumerate(value): input_attrs = dict(value=force_unicode(v), **final_attrs) if id_: # An ID attribute was given. Add a numeric index as a suffix # so that the inputs don't all have the same ID attribute. input_attrs['id'] = '%s_%s' % (id_, i) inputs.append(u'<input%s />' % flatatt(input_attrs)) return mark_safe(u'\n'.join(inputs))
def label_tag(self, contents=None, attrs=None): """ Wraps the given contents in a <label>, if the field has an ID attribute. Does not HTML-escape the contents. If contents aren't given, uses the field's HTML-escaped label. If attrs are given, they're used as HTML attributes on the <label> tag. """ contents = contents or conditional_escape(self.label) widget = self.field.widget id_ = widget.attrs.get("id") or self.auto_id if id_: attrs = attrs and flatatt(attrs) or "" contents = u'<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, unicode(contents)) return mark_safe(contents)
def label_tag(self, contents=None, attrs=None): """ Wraps the given contents in a <label>, if the field has an ID attribute. Does not HTML-escape the contents. If contents aren't given, uses the field's HTML-escaped label. If attrs are given, they're used as HTML attributes on the <label> tag. """ contents = contents or conditional_escape(self.label) widget = self.field.widget id_ = widget.attrs.get('id') or self.auto_id if id_: attrs = attrs and flatatt(attrs) or '' contents = u'<label for="%s"%s>%s</label>' % ( widget.id_for_label(id_), attrs, unicode(contents)) return mark_safe(contents)
def format(number, decimal_sep, decimal_pos, grouping=0, thousand_sep=''): """ Gets a number (as a number or string), and returns it as a string, using formats definied as arguments: * decimal_sep: Decimal separator symbol (for example ".") * decimal_pos: Number of decimal positions * grouping: Number of digits in every group limited by thousand separator * thousand_sep: Thousand separator symbol (for example ",") """ use_grouping = settings.USE_L10N and \ settings.USE_THOUSAND_SEPARATOR and grouping # Make the common case fast: if isinstance(number, int) and not use_grouping and not decimal_pos: return mark_safe(unicode(number)) # sign if float(number) < 0: sign = '-' else: sign = '' str_number = unicode(number) if str_number[0] == '-': str_number = str_number[1:] # decimal part if '.' in str_number: int_part, dec_part = str_number.split('.') if decimal_pos: dec_part = dec_part[:decimal_pos] else: int_part, dec_part = str_number, '' if decimal_pos: dec_part = dec_part + ('0' * (decimal_pos - len(dec_part))) if dec_part: dec_part = decimal_sep + dec_part # grouping if use_grouping: int_part_gd = '' for cnt, digit in enumerate(int_part[::-1]): if cnt and not cnt % grouping: int_part_gd += thousand_sep int_part_gd += digit int_part = int_part_gd[::-1] return sign + int_part + dec_part
def render(self, name, value, attrs=None): if self.is_localized: for widget in self.widgets: widget.is_localized = self.is_localized # value is a list of values, each corresponding to a widget # in self.widgets. if not isinstance(value, list): value = self.decompress(value) output = [] final_attrs = self.build_attrs(attrs) id_ = final_attrs.get('id', None) for i, widget in enumerate(self.widgets): try: widget_value = value[i] except IndexError: widget_value = None if id_: final_attrs = dict(final_attrs, id='%s_%s' % (id_, i)) output.append(widget.render(name + '_%s' % i, widget_value, final_attrs)) return mark_safe(self.format_output(output))
def localize(value, use_l10n=None): """ Checks if value is a localizable type (date, number...) and returns it formatted as a string using current locale format. If use_l10n is provided and is not None, that will force the value to be localized (or not), overriding the value of settings.USE_L10N. """ if isinstance(value, bool): return mark_safe(unicode(value)) elif isinstance(value, (decimal.Decimal, float, int, long)): return number_format(value, use_l10n=use_l10n) elif isinstance(value, datetime.datetime): return date_format(value, 'DATETIME_FORMAT', use_l10n=use_l10n) elif isinstance(value, datetime.date): return date_format(value, use_l10n=use_l10n) elif isinstance(value, datetime.time): return time_format(value, 'TIME_FORMAT', use_l10n=use_l10n) else: return value
def do_translate(message, translation_function): """ Translates 'message' using the given 'translation_function' name -- which will be either gettext or ugettext. It uses the current thread to find the translation object to use. If no current translation is activated, the message will be run through the default translation object. """ global _default eol_message = message.replace('\r\n', '\n').replace('\r', '\n') t = getattr(_active, "value", None) if t is not None: result = getattr(t, translation_function)(eol_message) else: if _default is None: from airy.core.conf import settings _default = translation(settings.LANGUAGE_CODE) result = getattr(_default, translation_function)(eol_message) if isinstance(message, SafeData): return mark_safe(result) return result
def render(self, name, value, attrs=None): if self.is_localized: for widget in self.widgets: widget.is_localized = self.is_localized # value is a list of values, each corresponding to a widget # in self.widgets. if not isinstance(value, list): value = self.decompress(value) output = [] final_attrs = self.build_attrs(attrs) id_ = final_attrs.get('id', None) for i, widget in enumerate(self.widgets): try: widget_value = value[i] except IndexError: widget_value = None if id_: final_attrs = dict(final_attrs, id='%s_%s' % (id_, i)) output.append( widget.render(name + '_%s' % i, widget_value, final_attrs)) return mark_safe(self.format_output(output))
def render(self, name, value, attrs=None): try: year_val, month_val, day_val = value.year, value.month, value.day except AttributeError: year_val = month_val = day_val = None if isinstance(value, basestring): if settings.USE_L10N: try: input_format = get_format('DATE_INPUT_FORMATS')[0] # Python 2.4 compatibility: # v = datetime.datetime.strptime(value, input_format) # would be clearer, but datetime.strptime was added in # Python 2.5 v = datetime.datetime(*(time.strptime(value, input_format)[0:6])) year_val, month_val, day_val = v.year, v.month, v.day except ValueError: pass else: match = RE_DATE.match(value) if match: year_val, month_val, day_val = [int(v) for v in match.groups()] choices = [(i, i) for i in self.years] year_html = self.create_select(name, self.year_field, value, year_val, choices) choices = MONTHS.items() month_html = self.create_select(name, self.month_field, value, month_val, choices) choices = [(i, i) for i in range(1, 32)] day_html = self.create_select(name, self.day_field, value, day_val, choices) output = [] for field in _parse_date_fmt(): if field == 'year': output.append(year_html) elif field == 'month': output.append(month_html) elif field == 'day': output.append(day_html) return mark_safe(u'\n'.join(output))
def render(self, name, value, attrs=None): substitutions = { 'initial_text': self.initial_text, 'input_text': self.input_text, 'clear_template': '', 'clear_checkbox_label': self.clear_checkbox_label, } template = u'%(input)s' substitutions['input'] = super(ClearableFileInput, self).render(name, value, attrs) if value and hasattr(value, "url"): template = self.template_with_initial substitutions['initial'] = (u'<a href="%s">%s</a>' % (escape(value.url), escape(force_unicode(value)))) if not self.is_required: checkbox_name = self.clear_checkbox_name(name) checkbox_id = self.clear_checkbox_id(checkbox_name) substitutions['clear_checkbox_name'] = conditional_escape(checkbox_name) substitutions['clear_checkbox_id'] = conditional_escape(checkbox_id) substitutions['clear'] = CheckboxInput().render(checkbox_name, False, attrs={'id': checkbox_id}) substitutions['clear_template'] = self.template_with_clear % substitutions return mark_safe(template % substitutions)
def gettext(message): result = TECHNICAL_ID_MAP.get(message, message) if isinstance(message, SafeData): return mark_safe(result) return result
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." top_errors = self.non_field_errors() # Errors that should be displayed above all fields. output, hidden_fields = [], [] for name, field in self.fields.items(): html_class_attr = "" bf = BoundField(self, field, name) bf_errors = self.error_class( [conditional_escape(error) for error in bf.errors] ) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend([u"(Hidden field %s) %s" % (name, force_unicode(e)) for e in bf_errors]) hidden_fields.append(unicode(bf)) else: # Create a 'class="..."' atribute if the row should have any # CSS classes applied. css_classes = bf.css_classes() if css_classes: html_class_attr = ' class="%s"' % css_classes if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = conditional_escape(force_unicode(bf.label)) # Only add the suffix if the label does not end in # punctuation. if self.label_suffix: if label[-1] not in ":?.!": label += self.label_suffix label = bf.label_tag(label) or "" else: label = "" if field.help_text: help_text = help_text_html % force_unicode(field.help_text) else: help_text = u"" output.append( normal_row % { "errors": force_unicode(bf_errors), "label": force_unicode(label), "field": unicode(bf), "help_text": help_text, "html_class_attr": html_class_attr, } ) if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u"".join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '</td></tr>') and # insert the hidden fields. if not last_row.endswith(row_ender): # This can happen in the as_p() case (and possibly others # that users write): if there are only top errors, we may # not be able to conscript the last row for our purposes, # so insert a new, empty row. last_row = normal_row % { "errors": "", "label": "", "field": "", "help_text": "", "html_class_attr": html_class_attr, } output.append(last_row) output[-1] = last_row[: -len(row_ender)] + str_hidden + row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe(u"\n".join(output))
def render(self, name, value, attrs=None): if value is None: value = '' final_attrs = self.build_attrs(attrs, name=name) return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), conditional_escape(force_unicode(value))))
def as_ul(self): "Returns this formset rendered as HTML <li>s." forms = u' '.join([form.as_ul() for form in self]) return mark_safe(u'\n'.join([unicode(self.management_form), forms]))
def render(self): return mark_safe(u'\n'.join(chain(*[getattr(self, 'render_' + name)() for name in MEDIA_TYPES])))
def render(self): """Outputs a <ul> for this set of radio fields.""" return mark_safe( u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % force_unicode(w) for w in self]))
def as_ul(self): if not self: return u'' return mark_safe(u'<ul class="errorlist">%s</ul>' % ''.join([u'<li>%s</li>' % conditional_escape(force_unicode(e)) for e in self]))
def render(self): """Outputs a <ul> for this set of radio fields.""" return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % force_unicode(w) for w in self]))
def escape(html): """ Returns the given HTML with ampersands, quotes and angle brackets encoded. """ return mark_safe(force_unicode(html).replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", '''))
def escapejs(value): """Hex encodes characters for use in JavaScript strings.""" for bad, good in _js_escapes: value = mark_safe(force_unicode(value).replace(bad, good)) return value
def render(self, name, value, attrs=None): if value is None: value = '' final_attrs = self.build_attrs(attrs, name=name) return mark_safe( u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), conditional_escape(force_unicode(value))))
def as_ul(self): if not self: return u'' return mark_safe(u'<ul class="errorlist">%s</ul>' % ''.join([ u'<li>%s%s</li>' % (k, force_unicode(v)) for k, v in self.items() ]))
def as_ul(self): if not self: return u'' return mark_safe(u'<ul class="errorlist">%s</ul>' % ''.join([ u'<li>%s</li>' % conditional_escape(force_unicode(e)) for e in self ]))
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." top_errors = self.non_field_errors( ) # Errors that should be displayed above all fields. output, hidden_fields = [], [] for name, field in self.fields.items(): html_class_attr = '' bf = BoundField(self, field, name) bf_errors = self.error_class([ conditional_escape(error) for error in bf.errors ]) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend([ u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors ]) hidden_fields.append(unicode(bf)) else: # Create a 'class="..."' atribute if the row should have any # CSS classes applied. css_classes = bf.css_classes() if css_classes: html_class_attr = ' class="%s"' % css_classes if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = conditional_escape(force_unicode(bf.label)) # Only add the suffix if the label does not end in # punctuation. if self.label_suffix: if label[-1] not in ':?.!': label += self.label_suffix label = bf.label_tag(label) or '' else: label = '' if field.help_text: help_text = help_text_html % force_unicode(field.help_text) else: help_text = u'' output.append( normal_row % { 'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text, 'html_class_attr': html_class_attr }) if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '</td></tr>') and # insert the hidden fields. if not last_row.endswith(row_ender): # This can happen in the as_p() case (and possibly others # that users write): if there are only top errors, we may # not be able to conscript the last row for our purposes, # so insert a new, empty row. last_row = (normal_row % { 'errors': '', 'label': '', 'field': '', 'help_text': '', 'html_class_attr': html_class_attr }) output.append(last_row) output[ -1] = last_row[:-len(row_ender)] + str_hidden + row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe(u'\n'.join(output))
def render(self): return mark_safe(u'\n'.join( chain(*[getattr(self, 'render_' + name)() for name in MEDIA_TYPES])))
def as_ul(self): if not self: return u'' return mark_safe(u'<ul class="errorlist">%s</ul>' % ''.join([u'<li>%s%s</li>' % (k, force_unicode(v)) for k, v in self.items()]))