def render(self, name, value, attrs=None): tags = [] if value is not None and not isinstance(value, str): # value contains a list a TaggedItem instances # Here we retrieve a comma-delimited list of tags # suitable for editing by the user tags = [o.tag for o in value.select_related('tag')] value = edit_string_for_tags(tags) elif value is not None: tags = split_strip(value) json_view = reverse('taggit_autocomplete_jqueryui_tag_list') html = '<div class="selector"><ul class="tags">' for tag in tags: html += (''' <li data-tag="%(name)s"> <span class="name">%(name)s</span> <a class="remove" href="#">X</a> </li>''' % {'name': tag}) html += '</ul>' html += super(TagAutocomplete, self).render(name, value, attrs) html += '<input type="text" id="%s_autocomplete"/></div>' % attrs['id'] js = ''' <script type="text/javascript"> (function (root) { root.taggit_init = root.taggit_init || []; root.taggit_init.push(['#%s_autocomplete', '%s']); })(window); </script>''' % (attrs['id'], json_view) return mark_safe("\n".join([html, js]))
def render(self, name, value, attrs=None): attrs.update({"class": "hidden"}) tags = [] if value is not None and not isinstance(value, basestring): # value contains a list a TaggedItem instances # Here we retrieve a comma-delimited list of tags # suitable for editing by the user tags = [o.tag for o in value.select_related('tag')] value = edit_string_for_tags(tags) elif value is not None: tags = [Tag(name=n.replace('"', '')) for n in split_strip(value)] json_view = reverse('taggit_autocomplete_jqueryui_tag_list') html = u'<div class="selector"><ul class="tags">' for tag in tags: html += (u''' <li data-tag="%(name)s"> <span class="name">%(name)s</span> <a class="remove" href="#">X</a> </li>''' % {'name': tag.name}) html += '</ul>' html += super(TagAutocomplete, self).render(name, value, attrs) html += u'<input type="text" id="%s_autocomplete"/></div>' % attrs['id'] js = u''' <script type="text/javascript"> (function (root) { root.taggit_init = root.taggit_init || []; root.taggit_init.push(['#%s_autocomplete', '%s']); })(window); </script>''' % (attrs['id'], json_view) return mark_safe("\n".join([html, js]))
def has_changed(self, initial, data): initial_list = [i.tag.name for i in initial] data_list = split_strip(data, ',') if len(initial_list) != len(data_list): return True initial_set = set(value for value in initial_list) data_set = set(value for value in data_list) return data_set != initial_set
def from_native(self, value): if not value: return [] if isinstance(value, six.string_types): value = split_strip(value) if isinstance(value, (list, tuple)): return [self._field.from_native(i) for i in value] raise ValidationError(self.error_messages['invalid'])
def to_native(self, value): if not value: value = [] if isinstance(value, six.string_types): value = split_strip(value) if isinstance(value, (list, tuple)): return [self._field.to_native(i) for i in value] return value
def parse_tags(tagstring): """ Parses tag input, with multiple word input being activated and delineated by commas and double quotes. Quotes take precedence, so they may contain commas. Returns a sorted list of unique tag names. Adapted from Taggit, modified to not split strings on spaces. Ported from Jonathan Buchanan's `django-tagging <http://django-tagging.googlecode.com/>`_ """ if not tagstring: return [] tagstring = force_text(tagstring) words = [] buffer = [] # Defer splitting of non-quoted sections until we know if there are # any unquoted commas. to_be_split = [] i = iter(tagstring) try: while True: c = six.next(i) if c == '"': if buffer: to_be_split.append(''.join(buffer)) buffer = [] c = six.next(i) while c != '"': buffer.append(c) c = six.next(i) if buffer: word = ''.join(buffer).strip() if word: words.append(word) buffer = [] else: buffer.append(c) except StopIteration: # If we were parsing an open quote which was never closed treat # the buffer as unquoted. if buffer: to_be_split.append(''.join(buffer)) if to_be_split: for chunk in to_be_split: words.extend( split_strip(chunk, settings.TAGGIT_SELECTIZE['DELIMITER'])) words = list(set(words)) words.sort() return words
def parse_tags(tagstring): """ Parses tag input, with multiple word input being activated and delineated by commas and double quotes. Quotes take precedence, so they may contain commas. Returns a sorted list of unique tag names. Adapted from Taggit, modified to not split strings on spaces. Ported from Jonathan Buchanan's `django-tagging <http://django-tagging.googlecode.com/>`_ """ if not tagstring: return [] tagstring = force_text(tagstring) words = [] buffer = [] # Defer splitting of non-quoted sections until we know if there are # any unquoted commas. to_be_split = [] i = iter(tagstring) try: while True: c = six.next(i) if c == '"': if buffer: to_be_split.append(''.join(buffer)) buffer = [] c = six.next(i) while c != '"': buffer.append(c) c = six.next(i) if buffer: word = ''.join(buffer).strip() if word: words.append(word) buffer = [] else: buffer.append(c) except StopIteration: # If we were parsing an open quote which was never closed treat # the buffer as unquoted. if buffer: to_be_split.append(''.join(buffer)) if to_be_split: for chunk in to_be_split: words.extend(split_strip(chunk, settings.TAGGIT_SELECTIZE['DELIMITER'])) words = list(set(words)) words.sort() return words
def parse_items(itemstring, sort=False): """Like taggit.utils.parse_tags, but without sorting""" if not itemstring: return [] itemstring = force_text(itemstring) words = [] buf = [] # Defer splitting of non-quoted sections until we know if there are # any unquoted commas. to_be_split = [] i = iter(itemstring) try: while True: c = six.next(i) if c == '"': if buf: to_be_split.append(''.join(buf)) buf = [] # Find the matching quote c = six.next(i) while c != '"': buf.append(c) c = six.next(i) if buf: word = ''.join(buf).strip() if word: words.append(word) buf = [] else: buf.append(c) except StopIteration: # If we were parsing an open quote which was never closed treat # the buffer as unquoted. if buf: to_be_split.append(''.join(buf)) if to_be_split: delimiter = ',' for chunk in to_be_split: words.extend(split_strip(chunk, delimiter)) if sort: words = list(set(words)) words.sort() return words
def from_native(self, value): if not value: return {} if isinstance(value, six.string_types): try: value = dict([i.split(':') for i in split_strip(value)]) except ValueError: raise ValidationError(self.error_messages['invalid']) if isinstance(value, dict): ret = {} for key, val in dict(value).items(): ret[self._key_field.from_native(key)] = self._val_field.from_native(val) return ret raise ValidationError(self.error_messages['invalid'])
def parse_tags(tagstring, sorted=True): """ Parses tag input, with multiple word input being activated and delineated by commas and double quotes. Quotes take precedence, so they may contain commas. Returns a sorted list of unique tag names, unless sorted=False. Ported from Jonathan Buchanan's `django-tagging <http://django-tagging.googlecode.com/>`_ """ if not tagstring: return [] tagstring = force_text(tagstring) # Special case - if there are no commas or double quotes in the # input, we don't *do* a recall... I mean, we know we only need to # split on spaces. if ',' not in tagstring and '"' not in tagstring: words = list(split_strip(tagstring, ' ')) if sorted: words.sort() return words words = [] buffer = [] # Defer splitting of non-quoted sections until we know if there are # any unquoted commas. to_be_split = [] saw_loose_comma = False open_quote = False i = iter(tagstring) try: while True: c = next(i) if c == '"': if buffer: to_be_split.append(''.join(buffer)) buffer = [] # Find the matching quote open_quote = True c = next(i) while c != '"': buffer.append(c) c = next(i) if buffer: word = ''.join(buffer).strip() if word: words.append(word) buffer = [] open_quote = False else: if not saw_loose_comma and c == ',': saw_loose_comma = True buffer.append(c) except StopIteration: # If we were parsing an open quote which was never closed treat # the buffer as unquoted. if buffer: if open_quote and ',' in buffer: saw_loose_comma = True to_be_split.append(''.join(buffer)) if to_be_split: if saw_loose_comma: delimiter = ',' else: delimiter = ' ' for chunk in to_be_split: words.extend(split_strip(chunk, delimiter)) words = list(words) if sorted: words.sort() return words
def test_should_return_empty_list_if_not_string(self): result = split_strip(None) self.assertListEqual(result, [])
def test_should_return_list_of_non_empty_words(self): expected_result = ["foo", "bar"] result = split_strip("foo|bar||", delimiter="|") self.assertListEqual(result, expected_result)
def parse_tags(tagstring, sorted=True): """ Parses tag input, with multiple word input being activated and delineated by commas and double quotes. Quotes take precedence, so they may contain commas. Returns a sorted list of unique tag names, unless sorted=False. Ported from Jonathan Buchanan's `django-tagging <http://django-tagging.googlecode.com/>`_ """ if not tagstring: return [] tagstring = force_unicode(tagstring) # Special case - if there are no commas or double quotes in the # input, we don't *do* a recall... I mean, we know we only need to # split on spaces. if u"," not in tagstring and u'"' not in tagstring: words = list(split_strip(tagstring, u" ")) if sorted: words.sort() return words words = [] buffer = [] # Defer splitting of non-quoted sections until we know if there are # any unquoted commas. to_be_split = [] saw_loose_comma = False open_quote = False i = iter(tagstring) try: while True: c = i.next() if c == u'"': if buffer: to_be_split.append(u"".join(buffer)) buffer = [] # Find the matching quote open_quote = True c = i.next() while c != u'"': buffer.append(c) c = i.next() if buffer: word = u"".join(buffer).strip() if word: words.append(word) buffer = [] open_quote = False else: if not saw_loose_comma and c == u",": saw_loose_comma = True buffer.append(c) except StopIteration: # If we were parsing an open quote which was never closed treat # the buffer as unquoted. if buffer: if open_quote and u"," in buffer: saw_loose_comma = True to_be_split.append(u"".join(buffer)) if to_be_split: if saw_loose_comma: delimiter = u"," else: delimiter = u" " for chunk in to_be_split: words.extend(split_strip(chunk, delimiter)) words = list(words) if sorted: words.sort() return words
def parse_items(itemstring): """Like taggit.utils.parse_tags, but without sorting""" if not itemstring: return [] itemstring = force_text(itemstring) # Special case - if there are no commas or double quotes in the # input, we don't *do* a recall... I mean, we know we only need to # split on spaces. if ',' not in itemstring and '"' not in itemstring: words = split_strip(itemstring, ' ') return words words = [] buf = [] # Defer splitting of non-quoted sections until we know if there are # any unquoted commas. to_be_split = [] saw_loose_comma = False open_quote = False i = iter(itemstring) try: while True: c = six.next(i) if c == '"': if buf: to_be_split.append(''.join(buf)) buf = [] # Find the matching quote open_quote = True c = six.next(i) while c != '"': buf.append(c) c = six.next(i) if buf: word = ''.join(buf).strip() if word: words.append(word) buf = [] open_quote = False else: if not saw_loose_comma and c == ',': saw_loose_comma = True buf.append(c) except StopIteration: # If we were parsing an open quote which was never closed treat # the buffer as unquoted. if buf: if open_quote and ',' in buf: saw_loose_comma = True to_be_split.append(''.join(buf)) if to_be_split: if saw_loose_comma: delimiter = ',' else: delimiter = ' ' for chunk in to_be_split: words.extend(split_strip(chunk, delimiter)) return words