def get_print_style(style=None, print_format=None, for_legacy=False): print_settings = frappe.get_doc("Print Settings") if not style: style = print_settings.print_style or "Standard" context = { "print_settings": print_settings, "print_style": style, "font": get_font(print_settings, print_format, for_legacy) } css = frappe.get_template("templates/styles/standard.css").render(context) try: css += frappe.get_template("templates/styles/" + style.lower() + ".css").render(context) except TemplateNotFound: pass # move @import to top for at_import in list(set(re.findall("(@import url\([^\)]+\)[;]?)", css))): css = css.replace(at_import, "") # prepend css with at_import css = at_import + css if print_format and print_format.css: css += "\n\n" + print_format.css return css
def get_print_style(style=None): print_settings = frappe.get_doc("Print Settings") if not style: style = print_settings.print_style or "Standard" context = {"print_settings": print_settings, "print_style": style} css = frappe.get_template("templates/styles/standard.css").render(context) try: additional_css = frappe.get_template("templates/styles/" + style.lower() + ".css").render(context) # move @import to top for at_import in list(set(re.findall("(@import url\([^\)]+\)[;]?)", additional_css))): additional_css = additional_css.replace(at_import, "") # prepend css with at_import css = at_import + css css += "\n" + additional_css except TemplateNotFound: pass return css
def build_template(context): """Returns a dict of block name and its rendered content""" out = {} render_blocks(context["template"], out, context) # set_sidebar(out, context) set_breadcrumbs(out, context) set_title_and_header(out, context) # meta if "meta_block" not in out: out["meta_block"] = frappe.get_template("templates/includes/meta_block.html").render(context) add_index(out, context) # render content_context = {} content_context.update(context) content_context.update(out) out["content"] = frappe.get_template("templates/includes/page_content.html").render(content_context) separate_style_and_script(out, context) add_hero(out, context) return out
def render_blocks(context): """returns a dict of block name and its rendered content""" out = {} env = frappe.get_jenv() def _render_blocks(template_path): source = frappe.local.jloader.get_source(frappe.local.jenv, template_path)[0] for referenced_template_path in meta.find_referenced_templates(env.parse(source)): if referenced_template_path: _render_blocks(referenced_template_path) template = frappe.get_template(template_path) for block, render in template.blocks.items(): out[block] = scrub_relative_urls(concat(render(template.new_context(context)))) _render_blocks(context["template_path"]) # default blocks if not found if "title" not in out and out.get("header"): out["title"] = out["header"] if "title" not in out: out["title"] = context.get("title") if "header" not in out and out.get("title"): out["header"] = out["title"] if not out["header"].startswith("<h"): out["header"] = "<h2>" + out["header"] + "</h2>" if "breadcrumbs" not in out: out["breadcrumbs"] = scrub_relative_urls( frappe.get_template("templates/includes/breadcrumbs.html").render(context)) if "<!-- no-sidebar -->" in out.get("content", ""): out["no_sidebar"] = 1 if "sidebar" not in out and not out.get("no_sidebar"): out["sidebar"] = scrub_relative_urls( frappe.get_template("templates/includes/sidebar.html").render(context)) out["title"] = strip_html(out.get("title") or "") # remove style and script tags from blocks out["style"] = re.sub("</?style[^<>]*>", "", out.get("style") or "") out["script"] = re.sub("</?script[^<>]*>", "", out.get("script") or "") return out
def make_web_page(self): # home page self.webpage = frappe.get_doc({ "doctype": "Web Page", "title": self.company, "published": 1, "header": "<h1>{0}</h1>".format(self.tagline or "Headline")+\ '<p>'+_("This is an example website auto-generated from ERPNext")+"</p>"+\ '<p><a class="btn btn-primary" href="/login">Login</a></p>', "description": self.company + ":" + (self.tagline or ""), "css": frappe.get_template("setup/page/setup_wizard/sample_home_page.css").render(), "main_section": frappe.get_template("setup/page/setup_wizard/sample_home_page.html").render({ "company": self.company, "tagline": (self.tagline or "") }) }).insert()
def get_summary_template(): global daily_summary_template if not daily_summary_template: daily_summary_template = frappe.get_template("templates/emails/daily_summary.html") return daily_summary_template
def make_blog(self): blogger = frappe.new_doc("Blogger") user = frappe.get_doc("User", self.user) blogger.user = self.user blogger.full_name = user.first_name + (" " + user.last_name if user.last_name else "") blogger.short_name = user.first_name.lower() blogger.avatar = user.user_image blogger.insert() blog_category = frappe.get_doc({ "doctype": "Blog Category", "category_name": "general", "published": 1, "title": _("General") }).insert() frappe.get_doc({ "doctype": "Blog Post", "title": "Welcome", "published": 1, "published_on": nowdate(), "blogger": blogger.name, "blog_category": blog_category.name, "blog_intro": "My First Blog", "content": frappe.get_template("setup/page/setup_wizard/sample_blog_post.html").render(), }).insert()
def make_toc(context, out): '''Insert full index (table of contents) for {index} tag''' from frappe.website.utils import get_full_index if '{index}' in out: html = frappe.get_template("templates/includes/full_index.html").render({ "full_index": get_full_index(), "url_prefix": context.url_prefix or "/", "route": context.route }) out = out.replace('{index}', html) if '{next}' in out: # insert next link next_item = None children_map = get_full_index() parent_route = os.path.dirname(context.route) children = children_map[parent_route] if parent_route and children: for i, c in enumerate(children): if c.route == context.route and i < (len(children) - 1): next_item = children[i+1] next_item.url_prefix = context.url_prefix or "/" if next_item: if next_item.route and next_item.title: html = ('<p class="btn-next-wrapper">'+_("Next")\ +': <a class="btn-next" href="{url_prefix}{route}">{title}</a></p>').format(**next_item) out = out.replace('{next}', html) return out
def suggest_user(term, group): pathname = get_pathname(group) if not get_access(pathname).get("admin"): raise frappe.PermissionError users = frappe.db.sql( """select pr.name, pr.first_name, pr.last_name, pr.user_image, pr.location from `tabUser` pr where (pr.first_name like %(term)s or pr.last_name like %(term)s) and pr.user_type = "Website User" and pr.user_image is not null and pr.enabled=1 and not exists(select wsp.name from `tabWebsite Route Permission` wsp where wsp.website_route=%(group)s and wsp.user=pr.name)""", {"term": "%{}%".format(term), "group": pathname}, as_dict=True, ) template = frappe.get_template("templates/includes/user_display.html") return [ { "value": "{} {}".format(pr.first_name or "", pr.last_name or ""), "user_html": template.render({"user": pr}), "user": pr.name, } for pr in users ]
def get_parent_post_html(post, context): user = frappe.get_doc("User", post.owner) for fieldname in ("first_name", "last_name", "user_image", "location"): post.set(fieldname, user.get(fieldname)) return frappe.get_template("templates/includes/inline_post.html")\ .render({"post": post, "view": context.view})
def send_archive_notification(self): template = "/templates/ip_library_templates/archive_notification.html" subject = "IP Document Archive Notification" email = list(set([self.archive_requester, self.ip_file_owner])) args = {"status":self.central_delivery_status, "comments":self.central_delivery_comments, "file_name":self.file_name} frappe.sendmail(recipients=email, sender=None, subject=subject, message=frappe.get_template(template).render(args))
def sync_entities(self, entity_type, entities): url = "http://digitales.com.au/api/rest/{entity_type}?filter[1][attribute]={field}&filter[1][eq]=%s" if entity_type == "Item": url = url.format( entity_type="products", field="sku" ) elif entity_type == "Sales Order": url = url.format( entity_type="orders", field="increment_id" ) sync_stat = {} for entity in entities: response = get_entity_from_magento(url%(entity), entity_type=entity_type, entity_id=entity) if response: idx = response.keys()[0] status = func_map[entity_type](response[idx]) sync_stat.update(status) if status else sync_stat.update({ entity: { "modified_date": response[idx].get("updated_at") or ""} }) else: sync_stat.update({ entity: { "operation": "Entity Not Found", "name": response.get("entity_id") if response and response.get("entity_id") else entity, } }) uri = "{url}/desk#Form/{dt}/".format(url=frappe.utils.get_url(), dt=entity_type) html = frappe.get_template("templates/status/sync_log_stat.html").render({"sync_stat": sync_stat, "uri":uri}) self.sync_stat = html.strip()
def set_breadcrumbs(out, context): """Build breadcrumbs template (deprecated)""" out["no_breadcrumbs"] = context.get("no_breadcrumbs", 0) or ("<!-- no-breadcrumbs -->" in out.get("content", "")) # breadcrumbs if not out["no_breadcrumbs"] and "breadcrumbs" not in out: out["breadcrumbs"] = frappe.get_template("templates/includes/breadcrumbs.html").render(context)
def send_login_mail(self, subject, template, add_args): """send mail with login details""" from frappe.utils.user import get_user_fullname from frappe.utils import get_url mail_titles = frappe.get_hooks().get("login_mail_title", []) title = frappe.db.get_default('company') or (mail_titles and mail_titles[0]) or "" full_name = get_user_fullname(frappe.session['user']) if full_name == "Guest": full_name = "Administrator" args = { 'first_name': self.first_name or self.last_name or "user", 'user': self.name, 'title': title, 'login_url': get_url(), 'user_fullname': full_name } args.update(add_args) sender = frappe.session.user not in STANDARD_USERS and frappe.session.user or None frappe.sendmail(recipients=self.email, sender=sender, subject=subject, message=frappe.get_template(template).render(args), as_bulk=self.flags.delay_emails)
def send_login_mail(self, subject, template, add_args, now=None): """send mail with login details""" from frappe.utils.user import get_user_fullname from frappe.utils import get_url mail_titles = frappe.get_hooks().get("login_mail_title", []) title = frappe.db.get_default("company") or (mail_titles and mail_titles[0]) or "" full_name = get_user_fullname(frappe.session["user"]) if full_name == "Guest": full_name = "Administrator" args = { "first_name": self.first_name or self.last_name or "user", "user": self.name, "title": title, "login_url": get_url(), "user_fullname": full_name, } args.update(add_args) sender = frappe.session.user not in STANDARD_USERS and get_formatted_email(frappe.session.user) or None frappe.sendmail( recipients=self.email, sender=sender, subject=subject, message=frappe.get_template(template).render(args), delayed=(not now) if now != None else self.flags.delay_emails, )
def build_page(path): if not getattr(frappe.local, "path", None): frappe.local.path = path context = get_context(path) if context.source: html = frappe.render_template(context.source, context) elif context.template: html = frappe.get_template(context.template).render(context) if '{index}' in html: html = html.replace('{index}', get_toc(context.route)) if '{next}' in html: html = html.replace('{next}', get_next_link(context.route)) # html = frappe.get_template(context.base_template_path).render(context) if can_cache(context.no_cache): page_cache = frappe.cache().hget("website_page", path) or {} page_cache[frappe.local.lang] = html frappe.cache().hset("website_page", path, page_cache) return html
def get_print_style(style=None, print_format=None, for_legacy=False): print_settings = frappe.get_doc("Print Settings") if not style: style = print_settings.print_style or '' context = { "print_settings": print_settings, "print_style": style, "font": get_font(print_settings, print_format, for_legacy) } css = frappe.get_template("templates/styles/standard.css").render(context) if style and frappe.db.exists('Print Style', style): css = css + '\n' + frappe.db.get_value('Print Style', style, 'css') # move @import to top for at_import in list(set(re.findall("(@import url\([^\)]+\)[;]?)", css))): css = css.replace(at_import, "") # prepend css with at_import css = at_import + css if print_format and print_format.css: css += "\n\n" + print_format.css return css
def notify_mentions(doc): if doc.communication_type != "Comment": return if doc.reference_doctype and doc.reference_name and doc.content and doc.comment_type=="Comment": mentions = extract_mentions(doc.content) if not mentions: return sender_fullname = get_fullname(frappe.session.user) parent_doc_label = "{0} {1}".format(_(doc.reference_doctype), doc.reference_name) subject = _("{0} mentioned you in a comment in {1}").format(sender_fullname, parent_doc_label) message = frappe.get_template("templates/emails/mentioned_in_comment.html").render({ "sender_fullname": sender_fullname, "comment": doc, "link": get_link_to_form(doc.reference_doctype, doc.reference_name, label=parent_doc_label) }) recipients = [frappe.db.get_value("User", {"enabled": 1, "username": username, "user_type": "System User"}) for username in mentions] frappe.sendmail( recipients=recipients, sender=frappe.session.user, subject=subject, message=message, bulk=True )
def add_index(out, context): """Add index, next button if `{index}`, `{next}` is present.""" # table of contents extn = "" if context.page_links_with_extn: extn = ".html" if "{index}" in out.get("content", "") and context.get("children"): html = frappe.get_template("templates/includes/full_index.html").render({ "full_index": get_full_index(context.pathname, extn = extn), "url_prefix": context.url_prefix }) out["content"] = out["content"].replace("{index}", html) # next and previous if "{next}" in out.get("content", ""): next_item = context.doc.get_next() next_item.extn = "" if context.doc.has_children(next_item.name) else extn if context.relative_links: next_item.name = next_item.page_name or "" else: if next_item and next_item.name and next_item.name[0]!="/": next_item.name = "/" + next_item.name if next_item and next_item.name: if not next_item.title: next_item.title = "" html = ('<p class="btn-next-wrapper"><a class="btn-next" href="{name}{extn}">'\ +_("Next")+': {title}</a></p>').format(**next_item) else: html = "" out["content"] = out["content"].replace("{next}", html)
def prepare_for_cd_notification(self): template = "/templates/ip_library_templates/upgrade_validity_request_notification.html" subject = "IP Document Upgrade Validity Notification" central_delivery = self.get_central_delivery() cc = [self.owner] if frappe.session.user != self.owner else [] args = {"user_name":frappe.session.user, "file_name":self.file_name } frappe.sendmail(recipients=central_delivery, sender=None, subject=subject, message=frappe.get_template(template).render(args), cc=cc)
def add_comment(args=None): """ args = { 'comment': '', 'comment_by': '', 'comment_by_fullname': '', 'comment_doctype': '', 'comment_docname': '', 'page_name': '', } """ if not args: args = frappe.local.form_dict args["doctype"] = "Comment" page_name = args.get("page_name") if "page_name" in args: del args["page_name"] if "cmd" in args: del args["cmd"] comment = frappe.get_doc(args) comment.ignore_permissions = True comment.insert() # since comments are embedded in the page, clear the web cache clear_cache(page_name) # notify commentors commentors = [ d[0] for d in frappe.db.sql( """select comment_by from tabComment where comment_doctype=%s and comment_docname=%s and ifnull(unsubscribed, 0)=0""", (comment.comment_doctype, comment.comment_docname), ) ] owner = frappe.db.get_value(comment.comment_doctype, comment.comment_docname, "owner") recipients = commentors if owner == "Administrator" else list(set(commentors + [owner])) from frappe.utils.email_lib.bulk import send send( recipients=recipients, doctype="Comment", email_field="comment_by", subject=_("New comment on {0} {1}").format(comment.comment_doctype, comment.comment_docname), message=_("{0} by {1}").format(markdown2.markdown(args.get("comment")), comment.comment_by_fullname), ref_doctype=comment.comment_doctype, ref_docname=comment.comment_docname, ) template = frappe.get_template("templates/includes/comment.html") return template.render({"comment": comment.as_dict()})
def get_attach_link(self, print_format): """Returns public link for the attachment via `templates/emails/print_link.html`.""" return frappe.get_template("templates/emails/print_link.html").render({ "url": get_url(), "doctype": self.reference_doctype, "name": self.reference_name, "print_format": print_format, "key": self.get_parent_doc().get_signature() })
def _render_blocks(template_path): source = frappe.local.jloader.get_source(frappe.local.jenv, template_path)[0] for referenced_template_path in meta.find_referenced_templates(env.parse(source)): if referenced_template_path: _render_blocks(referenced_template_path) template = frappe.get_template(template_path) for block, render in template.blocks.items(): out[block] = scrub_relative_urls(concat(render(template.new_context(context))))
def send_archive_notification(doc): template = "/templates/ip_library_templates/archive_request_notification.html" subject = "IP Document Archive Request Notification" central_delivery = frappe.get_list("UserRole", filters={"role":"Central Delivery","parent":["!=", "Administrator"]}, fields=["parent"]) central_delivery = [user.get("parent") for user in central_delivery] args = {"user_name":frappe.session.user, "file_name":doc.get("file_name")} cc = [doc.get("owner")] if frappe.session.user != doc.get("owner") else [] frappe.sendmail(recipients=central_delivery, sender=None, subject=subject, message=frappe.get_template(template).render(args), cc=cc)
def build_page(path): context = get_context(path) html = frappe.get_template(context.base_template_path).render(context) html = scrub_relative_urls(html) if can_cache(context.no_cache): frappe.cache().set_value("page:" + path, html) return html
def send_login_mail(subject, template, args): """send mail with login details""" STANDARD_USERS = ("Guest", "Administrator") sender = frappe.session.user not in STANDARD_USERS and frappe.session.user or None try: data = frappe.sendmail(recipients=args.get('email_id'), sender=sender, subject=subject, message=frappe.get_template(template).render(args)) msgprint("Sent email successfully to customer {0}".format(args.get('first_name'))) except Exception, e: msgprint(e)
def get_post_list_html(group, view, limit_start=0, limit_length=20): from frappe.templates.generators.website_group import get_views # verify permission for paging if frappe.local.form_dict.cmd == "get_post_list_html": pathname = frappe.db.get_value("Website Route", {"ref_doctype": "Website Group", "docname": group}) access = get_access(pathname) if not access.get("read"): return frappe.PermissionError conditions = "" values = [group] group_type = frappe.db.get_value("Website Group", group, "group_type") if group_type == "Events": # should show based on time upto precision of hour # because the current hour should also be in upcoming values.append(now_datetime().replace(minute=0, second=0, microsecond=0)) if view in ("feed", "closed"): order_by = "p.creation desc" if view == "closed": conditions += " and p.is_task=1 and p.status='Closed'" elif view in ("popular", "open"): now = get_datetime_str(now_datetime()) order_by = """(p.upvotes + post_reply_count - (timestampdiff(hour, p.creation, \"{}\") / 2)) desc, p.creation desc""".format(now) if view == "open": conditions += " and p.is_task=1 and p.status='Open'" elif view == "upcoming": conditions += " and p.is_event=1 and p.event_datetime >= %s" order_by = "p.event_datetime asc" elif view == "past": conditions += " and p.is_event=1 and p.event_datetime < %s" order_by = "p.event_datetime desc" values += [int(limit_start), int(limit_length)] posts = frappe.db.sql("""select p.*, pr.user_image, pr.first_name, pr.last_name, (select count(pc.name) from `tabPost` pc where pc.parent_post=p.name) as post_reply_count from `tabPost` p, `tabUser` pr where p.website_group = %s and pr.name = p.owner and ifnull(p.parent_post, '')='' {conditions} order by {order_by} limit %s, %s""".format(conditions=conditions, order_by=order_by), tuple(values), as_dict=True, debug=True) context = { "posts": posts, "limit_start": limit_start, "view": get_views(group_type)[view] } return frappe.get_template("templates/includes/post_list.html").render(context)
def get_toc(route, url_prefix=None, app=None): '''Insert full index (table of contents) for {index} tag''' from frappe.website.utils import get_full_index full_index = get_full_index(app=app) return frappe.get_template("templates/includes/full_index.html").render({ "full_index": full_index, "url_prefix": url_prefix or "/", "route": route.rstrip('/') })
def get_item_for_list_in_html(context): # add missing absolute link in files # user may forget it during upload if (context.get("website_image") or "").startswith("files/"): context["website_image"] = "/" + urllib.quote(context["website_image"]) products_template = 'templates/includes/products_as_grid.html' if cint(frappe.db.get_single_value('Products Settings', 'products_as_list')): products_template = 'templates/includes/products_as_list.html' return frappe.get_template(products_template).render(context)
def render_blocks(template_path, out, context): """Build the template block by block from the main template.""" env = frappe.get_jenv() source = frappe.local.jloader.get_source(frappe.local.jenv, template_path)[0] for referenced_template_path in meta.find_referenced_templates(env.parse(source)): if referenced_template_path: render_blocks(referenced_template_path, out, context) template = frappe.get_template(template_path) for block, render in template.blocks.items(): new_context = template.new_context(context) out[block] = concat(render(new_context))
def get_attach_link(url): """Returns public link for the attachment via `templates/emails/print_link.html`.""" return frappe.get_template("templates/emails/print_link.html").render( {"url": "%s/%s" % (frappe.utils.get_url(), url)})
def get_list_item(doc): return frappe.get_template( "erpnext_community_portal/doctype/frappe_partner/list_item.html" ).render(doc)
def write_files(self): """render templates and write files to target folder""" frappe.local.flags.home_page = "index" cnt = 0 for page in frappe.db.sql("""select parent_website_route, page_name from `tabWeb Page` where ifnull(template_path, '')!=''""", as_dict=True): if page.parent_website_route: path = page.parent_website_route + "/" + page.page_name else: path = page.page_name print "Writing {0}".format(path) # set this for get_context / website libs frappe.local.path = path context = { "page_links_with_extn": True, "relative_links": True, "docs_base_url": self.docs_base_url, "url_prefix": self.docs_base_url, } context.update(self.app_context) context = get_context(path, context) target_path_fragment = context.template_path.split('/docs/', 1)[1] target_filename = os.path.join(self.target, target_path_fragment) # rename .md files to .html if target_filename.rsplit(".", 1)[1] == "md": target_filename = target_filename[:-3] + ".html" context.brand_html = context.top_bar_items = context.favicon = None self.docs_config.get_context(context) if not context.brand_html: if context.docs_icon: context.brand_html = '<i class="{0}"></i> {1}'.format( context.docs_icon, context.app.title) else: context.brand_html = context.app.title if not context.top_bar_items: context.top_bar_items = [ # {"label": "Contents", "url": self.docs_base_url + "/contents.html", "right": 1}, { "label": "User Guide", "url": self.docs_base_url + "/user", "right": 1 }, { "label": "Developer Docs", "url": self.docs_base_url + "/current", "right": 1 }, ] context.top_bar_items = [{ "label": '<i class="octicon octicon-search"></i>', "url": "#", "right": 1 }] + context.top_bar_items if not context.favicon: context.favicon = "/assets/img/favicon.ico" context.only_static = True context.base_template_path = "templates/autodoc/base_template.html" html = frappe.get_template( "templates/generators/web_page.html").render(context) if not "<!-- autodoc -->" in html: html = html.replace('<!-- edit-link -->', edit_link.format(\ source_link = self.docs_config.source_link, app_name = self.app, branch = context.app.branch, target = target_path_fragment)) if not os.path.exists(os.path.dirname(target_filename)): os.makedirs(os.path.dirname(target_filename)) with open(target_filename, "w") as htmlfile: htmlfile.write(html.encode("utf-8")) cnt += 1 print "Wrote {0} files".format(cnt)
def render_blocks(context): """returns a dict of block name and its rendered content""" out = {} env = frappe.get_jenv() def _render_blocks(template_path): source = frappe.local.jloader.get_source(frappe.local.jenv, template_path)[0] for referenced_template_path in meta.find_referenced_templates( env.parse(source)): if referenced_template_path: _render_blocks(referenced_template_path) template = frappe.get_template(template_path) for block, render in template.blocks.items(): out[block] = scrub_relative_urls( concat(render(template.new_context(context)))) _render_blocks(context["template"]) # default blocks if not found if "title" not in out and out.get("header"): out["title"] = out["header"] if "title" not in out: out["title"] = context.get("title") if "header" not in out and out.get("title"): out["header"] = out["title"] if out.get("header") and not out["header"].startswith("<h"): out["header"] = "<h2>" + out["header"] + "</h2>" if "breadcrumbs" not in out: if context.doc and hasattr(context.doc, "get_parents"): context.parents = context.doc.get_parents(context) out["breadcrumbs"] = scrub_relative_urls( frappe.get_template("templates/includes/breadcrumbs.html").render( context)) if "meta_block" not in out: out["meta_block"] = frappe.get_template( "templates/includes/meta_block.html").render(context) out["no_sidebar"] = context.get("no_sidebar", 0) if "<!-- no-sidebar -->" in out.get("content", ""): out["no_sidebar"] = 1 if "<!-- title:" in out.get("content", ""): out["title"] = re.findall('<!-- title:([^>]*) -->', out.get("content"))[0].strip() if "{index}" in out.get("content", "") and context.get("children"): html = frappe.get_template( "templates/includes/static_index.html").render( {"items": context["children"]}) out["content"] = out["content"].replace("{index}", html) if "{next}" in out.get("content", ""): next_item = context.doc.get_next() if next_item: if next_item.name[0] != "/": next_item.name = "/" + next_item.name html = '''<p><br><a href="{name}" class="btn btn-primary"> {title} <i class="icon-chevron-right"></i></a> </p>'''.format(**next_item) out["content"] = out["content"].replace("{next}", html) if "sidebar" not in out and not out.get("no_sidebar"): out["sidebar"] = scrub_relative_urls( frappe.get_template("templates/includes/sidebar.html").render( context)) out["title"] = strip_html(out.get("title") or "") # remove style and script tags from blocks out["style"] = re.sub("</?style[^<>]*>", "", out.get("style") or "") out["script"] = re.sub("</?script[^<>]*>", "", out.get("script") or "") return out