def generate_slug(name, language="en", max_length=100, allowed="abcdefghijklmnopqrstuvwxyz0123456789_-", default="slug"): """ generate a slug based on a title / sentence """ from wheelcms_axle.stopwords import stopwords import re name = name.lower() name_no_stopwords = " ".join(x for x in name.split() if x not in set(stopwords.get(language, []))) slug = re.sub("[^%s]+" % allowed, "-", name_no_stopwords, )[:max_length].strip("-") slug = re.sub("-+", "-", slug) return slug or default
def clean_slug(self): if self.attach: return slug = self.data.get("slug", "").strip().lower() language = self.data.get("language", settings.FALLBACK) ## XXX move the whole slug generation / stopwords stuff to separate method title = self.cleaned_data.get("title", "").lower() title_no_sw = " ".join(x for x in title.split() if x not in set(stopwords.get(language, []))) parent_path = self.parent.get_path(language=language) if not slug: slug = re.sub("[^%s]+" % Node.ALLOWED_CHARS, "-", title_no_sw)[: Node.MAX_PATHLEN].strip("-") slug = re.sub("-+", "-", slug) ## slug may be empty now by all space/stopwords/dash removal if not slug: slug = "node" existing = Node.get(path=parent_path + "/" + slug, language=language) base_slug = slug[: Node.MAX_PATHLEN - 6] ## some space for counter count = 1 while (existing and existing != self.node) or (slug in self.reserved): slug = base_slug + str(count) existing = Node.get(path=self.parent.path + "/" + slug, language=language) count += 1 if slug in self.reserved: raise forms.ValidationError("This is a reserved name") if not Node.validpathre.match(slug): raise forms.ValidationError("Only numbers, letters, _-") existing = Node.get(path=parent_path + "/" + slug, language=language) if existing and existing != self.node: raise forms.ValidationError("Name in use") return slug