Started with Website Group rendering (#421)version-14
@@ -532,14 +532,14 @@ jenv = None | |||
def get_jenv(): | |||
global jenv | |||
if not jenv: | |||
from jinja2 import Environment, ChoiceLoader, PackageLoader | |||
from jinja2 import Environment, ChoiceLoader, PackageLoader, DebugUndefined | |||
apps = get_installed_apps() | |||
apps.remove("webnotes") | |||
# webnotes will be loaded last, so app templates will get precedence | |||
jenv = Environment(loader = ChoiceLoader([PackageLoader(app, ".") \ | |||
for app in apps + ["webnotes"]])) | |||
for app in apps + ["webnotes"]]), undefined=DebugUndefined) | |||
set_filters(jenv) | |||
@@ -38,7 +38,6 @@ class DocType: | |||
make_module_and_roles(self.doclist, "Page Role") | |||
if not webnotes.flags.in_import and getattr(conf,'developer_mode', 0) and self.doc.standard=='Yes': | |||
print "here" | |||
from webnotes.modules.export_file import export_to_files | |||
from webnotes.modules import get_module_path, scrub | |||
import os | |||
@@ -14,9 +14,10 @@ app_include_css = assets/webnotes/css/splash.css | |||
app_include_css = assets/css/webnotes.css | |||
web_include_js = assets/js/webnotes-web.min.js | |||
web_include_css = assets/css/webnotes-web.css | |||
website_group_views:Forum = webnotes.templates.website_group.forum.get_views | |||
website_group_views:Events = webnotes.templates.website_group.events.get_views | |||
website_group_views:Tasks = webnotes.templates.website_group.tasks.get_views | |||
website_group_handler:Forum = webnotes.templates.website_group.forum | |||
website_group_handler:Events = webnotes.templates.website_group.events | |||
website_group_handler:Tasks = webnotes.templates.website_group.tasks | |||
get_desktop_icons = webnotes.manage.get_desktop_icons | |||
notification_config = webnotes.core.notifications.get_notification_config | |||
@@ -11,7 +11,7 @@ | |||
<link rel="icon" href="{{ favicon | scrub_relative_url }}" type="image/x-icon"> | |||
{%- block head -%} | |||
{%- if meta_description -%} | |||
{%- if meta_description is defined -%} | |||
<meta name="description" content="{{ meta_description }}"> | |||
{%- endif -%} | |||
@@ -25,13 +25,13 @@ | |||
{%- endblock -%} | |||
{%- block javascript -%} | |||
{%- if javascript -%} | |||
{%- if javascript is defined -%} | |||
<script>{{ javascript }}</script> | |||
{%- endif -%} | |||
{%- endblock -%} | |||
{%- block css -%} | |||
{%- if css -%} | |||
{%- if css is defined -%} | |||
<style>{{ css }}</style> | |||
{%- endif -%} | |||
{%- endblock -%} | |||
@@ -39,18 +39,38 @@ | |||
{%- block style -%}{%- endblock -%} | |||
</head> | |||
<body> | |||
{%- block banner -%} | |||
{% if banner_html -%} | |||
<header class="container">{{ banner_html or "" }}</header> | |||
{%- endif %} | |||
{%- endblock -%} | |||
<div id="wrap"> | |||
{%- block banner -%} | |||
{% if banner_html -%} | |||
<header class="container">{{ banner_html or "" }}</header> | |||
{%- endif %} | |||
{%- endblock -%} | |||
{%- block navbar -%}{% include "templates/includes/navbar.html" %}{%- endblock -%} | |||
{%- block navbar -%}{% include "templates/includes/navbar.html" %}{%- endblock -%} | |||
<div class="page-container" id="page-{{ name or page_name }}"> | |||
{%- block content -%}{{ content }}{%- endblock -%} | |||
<header class="page-header"> | |||
<div class="container"> | |||
{%- if header is defined -%}{{ header }}{%- endif -%} | |||
</div> | |||
</header> | |||
<div class="container page-container" id="page-{{ name or page_name }}"> | |||
<div class="row"> | |||
<div class="col-sm-9 page-content"> | |||
{%- block content -%}{{ content }}{%- endblock -%} | |||
</div> | |||
<div class="col-sm-3 page-sidebar"> | |||
{%- block sidebar -%}{%- if sidebar is defined -%}{{ sidebar }}{%- endif -%}{%- endblock -%} | |||
</div> | |||
</div> | |||
</div> | |||
<footer class="page-footer"> | |||
<div class="container"> | |||
{%- if footer is defined -%}{{ footer }}{%- endif -%} | |||
</div> | |||
</footer> | |||
</div> | |||
<div id="footer"> | |||
{%- block footer -%}{% include "templates/includes/footer.html" %}{%- endblock -%} | |||
</div> | |||
{%- block footer -%}{% include "templates/includes/footer.html" %}{%- endblock -%} | |||
</body> | |||
</html> |
@@ -1,7 +1,13 @@ | |||
{% block content %} | |||
<div class="container content" itemscope itemtype="http://schema.org/BlogPost"> | |||
<h2 itemprop="name headline">{{ title }}</h2> | |||
{% block title %} {{ title }} {% endblock %} | |||
{% block header %} | |||
<h2 itemprop="name headline" itemscope itemtype="http://schema.org/BlogPost"> | |||
{{ title }} | |||
</h2> | |||
{% endblock %} | |||
{% block content %} | |||
<div class="blog-content" itemscope itemtype="http://schema.org/BlogPost"> | |||
<!-- begin blog content --> | |||
<div class="help" style="color: #aaa"> | |||
<span itemprop="author">{{ blogger_info and blogger_info.full_name or full_name }}</span> / | |||
@@ -29,5 +35,8 @@ $(function() { | |||
} | |||
}); | |||
</script> | |||
{% include 'templates/includes/blog_footer.html' %} | |||
{% endblock %} | |||
{% endblock %} | |||
{% block footer %}{% include 'templates/includes/blog_footer.html' %}{% endblock %} | |||
{% block sidebar %}{% include "templates/includes/sidebar.html" %}{% endblock %} |
@@ -6,6 +6,7 @@ from __future__ import unicode_literals | |||
import markdown2 | |||
import webnotes | |||
from webnotes.utils import global_date_format, get_fullname, cint | |||
from webnotes.webutils import render_blocks | |||
doctype = "Blog Post" | |||
condition_field = "published" | |||
@@ -36,7 +37,7 @@ def get_context(context): | |||
blog_post.fields.update(context) | |||
return { "title": blog_post.title, "content": context.template.render(blog_post.fields) } | |||
return render_blocks(blog_post.fields) | |||
@webnotes.whitelist(allow_guest=True) | |||
def get_blog_list(start=0, by=None, category=None): | |||
@@ -1,10 +1,11 @@ | |||
{% extends base_template %} | |||
{% block title %} {{ title }} {% endblock %} | |||
{% block header %}{% if show_title %}<h2>{{ title }}</h2>{% endif %}{% endblock %} | |||
{% block content %} | |||
<div class="container content"> | |||
<div class="webpage-content"> | |||
{# title, breadcrumbs, table of contents #} | |||
{% block pre_content -%} | |||
{% if show_title %}<h1>{{ title }}</h1>{% endif %} | |||
{% if show_breadcrumbs and breadcrumbs -%} | |||
<ul class="breadcrumb"> | |||
{% for b in breadcrumbs -%} | |||
@@ -65,3 +66,5 @@ $(function() { | |||
}); | |||
</script> | |||
{% endblock %} | |||
{% block sidebar %}{% include "templates/includes/sidebar.html" %}{% endblock %} |
@@ -1,2 +1,89 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.webutils import render_blocks | |||
from webnotes.website.doctype.website_slideshow.website_slideshow import get_slideshow | |||
doctype = "Web Page" | |||
condition_field = "published" | |||
condition_field = "published" | |||
def get_context(context): | |||
web_page = webnotes.bean(context.ref_doctype, context.docname) | |||
if web_page.doc.slideshow: | |||
get_slideshow(web_page) | |||
web_page.doc.meta_description = web_page.doc.description | |||
web_page.doc.breadcrumbs = get_breadcrumbs(web_page) | |||
web_page.doc.toc_list = get_toc_list(web_page) | |||
# parent, child, next sibling links | |||
web_page.doc.links = get_navigation_links(web_page) | |||
if web_page.doc.enable_comments: | |||
web_page.doc.comment_list = webnotes.conn.sql("""select | |||
comment, comment_by_fullname, creation | |||
from `tabComment` where comment_doctype="Web Page" | |||
and comment_docname=%s order by creation""", web_page.doc.name, as_dict=1) or [] | |||
web_page.doc.fields.update(context) | |||
return render_blocks(web_page.doc.fields) | |||
def get_breadcrumbs(web_page): | |||
breadcrumbs = [] | |||
def add_parent_of(web_page): | |||
parent = webnotes.conn.sql("""select name, page_name, title from `tabWeb Page` | |||
where exists (select parent from `tabTable of Contents` | |||
where `tabTable of Contents`.parent=`tabWeb Page`.name | |||
and web_page=%s)""", web_page, as_dict=True) | |||
if parent and parent[0]: | |||
parent = parent[0] | |||
add_parent_of(parent.name) | |||
breadcrumbs.append(parent) | |||
add_parent_of(web_page.doc.name) | |||
return breadcrumbs | |||
def get_toc_list(web_page): | |||
toc_list = web_page.doclist.get({"parentfield": "toc"}) | |||
if not toc_list: return [] | |||
out = webnotes.conn.sql("""select name, page_name, title | |||
from `tabWeb Page` where name in (%s)""" % \ | |||
(", ".join(["%s"]*len(toc_list))), | |||
tuple([d.web_page for d in toc_list]), | |||
as_dict=True) | |||
toc_idx = dict(((toc.web_page, toc.idx) for toc in toc_list)) | |||
return sorted(out, key=lambda x: toc_idx.get(x.name)) | |||
def get_navigation_links(web_page): | |||
links = {} | |||
if web_page.doc.toc_list: | |||
links["child"] = web_page.doc.toc_list[0] | |||
if web_page.doc.breadcrumbs: | |||
if web_page.doc.breadcrumbs[-1]: | |||
links["parent"] = web_page.doc.breadcrumbs[-1] | |||
def set_next(current, parent, breadcrumbs): | |||
web_page = webnotes.get_obj("Web Page", parent) | |||
toc_list = web_page.get_toc_list() | |||
for i, toc in enumerate(toc_list): | |||
if toc.name == current and ((i+1)<len(toc_list)): | |||
links["next"] = toc_list[i+1] | |||
break | |||
if not links.get("next") and breadcrumbs: | |||
set_next(parent, breadcrumbs[-1].name, breadcrumbs[:-1]) | |||
set_next(web_page.doc.name, web_page.doc.breadcrumbs[-1].name, web_page.doc.breadcrumbs[:-1]) | |||
return links |
@@ -1,15 +1,35 @@ | |||
{% extends base_template %} | |||
{% block title %}{{ title }}{% endblock %} | |||
{% block header %} | |||
<h2>{{ group.group_title }}</h2> | |||
{%- if group.group_description -%} | |||
<p class="lead">{{ group.group_description }}</p> | |||
{%- endif -%} | |||
{% endblock %} | |||
{% block content %} | |||
{{ content }} | |||
<ul class="nav nav-tabs view-selector"> | |||
{%- for t in views -%} | |||
<li class="{% if view.name==t.name -%} active {%- endif %} {% if t.hidden -%} hide {%- endif %}" | |||
data-view="{{ t.view }}"> | |||
<a href="{{ t.url or '' }}"><i class="{{ t.icon }}"></i> | |||
<span class="nav-label">{{ t.label }}</span></a> | |||
</li> | |||
{%- endfor -%} | |||
</ul> | |||
{% include view.template_path %} | |||
{%- if access -%} | |||
<script> | |||
$(function() { | |||
wn.provide("wn"); | |||
wn.access = {{ access|json }}; | |||
wn.provide("website"); | |||
website.access = {{ access|json }}; | |||
website.group = "{{ group.name }}"; | |||
website.view = "{{ view.name }}"; | |||
}) | |||
</script> | |||
{%- endif -%} | |||
{% endblock %} | |||
{% block sidebar %}{% include "templates/includes/sidebar.html" %}{% endblock %} |
@@ -2,23 +2,24 @@ | |||
# MIT License. See license.txt | |||
import webnotes | |||
from webnotes.webutils import get_access | |||
from webnotes.webutils import get_access, render_blocks, can_cache | |||
doctype = "Website Group" | |||
no_cache = 1 | |||
def get_context(controller, page_options): | |||
group, view = guess_group_view(controller, page_options) | |||
def get_context(context): | |||
bean = webnotes.bean(context.ref_doctype, context.docname) | |||
group, view = guess_group_view(bean, context) | |||
try: | |||
if not has_access(group, view): | |||
raise webnotes.PermissionError | |||
group_context = get_group_context(group, view, bean) | |||
group_context["access"] = get_access(group) | |||
group_context.update(context) | |||
context = get_initial_context(group, view, controller) | |||
context["access"] = get_access(group) | |||
context["content"] = get_content(context) | |||
return context | |||
return render_blocks(group_context) | |||
except webnotes.DoesNotExistError: | |||
return { | |||
@@ -31,69 +32,65 @@ def get_context(controller, page_options): | |||
'You are not permitted to view this page.</div>' | |||
} | |||
def get_initial_context(group, view, controller): | |||
def _get_initial_context(): | |||
if controller: | |||
group = controller.doc | |||
else: | |||
group = webnotes.doc("Website Group", group) | |||
# move all this to webutils | |||
parents = webnotes.conn.sql("""select name, unit_title from tabUnit | |||
where lft < %s and rgt > %s order by lft asc""", (unit.lft, unit.rgt), as_dict=1) | |||
# update title | |||
title = unit.unit_title | |||
views = get_views(unit) | |||
view_options = views.get(view, {}) | |||
if view_options: | |||
title += " - " + view_options["label"] | |||
def get_group_context(group, view, bean): | |||
cache_key = "website_group_context:{}:{}".format(group, view) | |||
views = get_views(bean.doc.group_type) | |||
view = views.get(view) | |||
if can_cache(view.get("no_cache")): | |||
group_context = webnotes.cache().get_value(cache_key) | |||
if group_context: | |||
return group_context | |||
group_context = build_group_context(group, view, bean, views) | |||
if can_cache(view.get("no_cache")): | |||
webnotes.cache().set_value(cache_key, group_context) | |||
views = sorted([opts for v, opts in views.items()], key=lambda d: d.get("idx")) | |||
context = { | |||
"name": unit.name, | |||
"public_read": unit.public_read, | |||
"title": "Aam Aadmi Party: " + title, | |||
"unit_title": title, | |||
"public_write": unit.public_write, | |||
"parents": parents, | |||
"children": get_child_unit_items(unit.name, public_read=1), | |||
"unit": unit.fields, | |||
"view": view, | |||
"views": views, | |||
"view_options": view_options | |||
} | |||
return context | |||
if webnotes.conf.get("disable_website_cache"): | |||
return _get_unit_context(unit, view) | |||
return group_context | |||
return webnotes.cache().get_value("unit_context:{unit}:{view}".format(unit=unit.lower(), view=view), | |||
lambda:_get_unit_context(unit, view)) | |||
def build_group_context(group, view, bean, views): | |||
title = "{} - {}".format(bean.doc.group_title, view.get("label")) | |||
def get_content(context): | |||
pass | |||
for name, opts in views.iteritems(): | |||
opts["url"] = opts["url"].format(group=group, post="") | |||
group_context = webnotes._dict({ | |||
"group": bean.doc.fields, | |||
"view": view, | |||
"views": (v[1] for v in sorted(views.iteritems(), key=lambda (k, v): v.get("idx"))), | |||
"title": title | |||
}) | |||
handler = get_handler(bean.doc.group_type) | |||
if handler: | |||
group_context.update(handler.get_context(group_context)) | |||
return group_context | |||
def guess_group_view(controller, page_options): | |||
group = page_options.docname | |||
def guess_group_view(bean, context): | |||
group = context.docname | |||
view = webnotes.form_dict.view | |||
view = None | |||
pathname = webnotes.request.path[1:] | |||
if "/" in pathname: | |||
view = pathname.split("/", 1)[1] | |||
if not view: | |||
get_views = webnotes.get_hooks("website_group_views:{}".controller.doc.group_type) | |||
if get_views: | |||
for v, opts in webnotes.get_attr(get_views)(group).items(): | |||
if opts.get("default"): | |||
view = v | |||
break | |||
for v, opts in get_views(bean.doc.group_type).iteritems(): | |||
if opts.get("default"): | |||
view = v | |||
break | |||
return group, view | |||
def get_handler(group_type): | |||
handler = webnotes.get_hooks("website_group_handler:{}".format(group_type)) | |||
if handler: | |||
return webnotes.get_module(handler[0]) | |||
def get_views(group_type): | |||
handler = get_handler(group_type) | |||
if handler and hasattr(handler, "get_views"): | |||
return handler.get_views() | |||
return {} | |||
def has_access(group, view): | |||
access = get_access(group) | |||
@@ -102,4 +99,4 @@ def has_access(group, view): | |||
elif view in ("add", "edit"): | |||
return access.get("write") | |||
else: | |||
return access.get("read") | |||
return access.get("read") |
@@ -64,10 +64,10 @@ var blog = { | |||
</div>\ | |||
</div>\ | |||
<div class="col-md-11">\ | |||
<h4><a href="%(page_name)s">%(title)s</a></h4>\ | |||
<h4><a href="/%(page_name)s">%(title)s</a></h4>\ | |||
<p>%(content)s</p>\ | |||
<p style="color: #aaa; font-size: 90%">\ | |||
<a href="blog?by=%(blogger)s&by_name=%(full_name)s">\ | |||
<a href="/blog?by=%(blogger)s&by_name=%(full_name)s">\ | |||
%(full_name)s</a> wrote this on %(published)s / %(comment_text)s</p>\ | |||
</div>\ | |||
</div><hr>', b)).appendTo($wrap); | |||
@@ -1,13 +1,14 @@ | |||
<div class="container content"> | |||
<hr /> | |||
{% if categories %} | |||
<h5>Explore posts by categories</h5> | |||
<ul class="breadcrumb" style="background-color: transparent; padding-left: 20px;"> | |||
{% for category in webnotes.conn.sql_list("select name from `tabBlog Category` order by name") %} | |||
<li><a href="blog?category={{ category }}">{{ category }}</a> | |||
{% endfor %} | |||
</ul> | |||
<br><br> | |||
{% endif %} | |||
<p>Show posts by <a href="blog">everyone</a>. Meet the <a href="writers">writers</a> of this blog</p> | |||
<div class="blog-footer"> | |||
<p> | |||
{% if categories %} | |||
<h5>Explore posts by categories</h5> | |||
<ul class="breadcrumb" style="background-color: transparent; padding-left: 20px;"> | |||
{% for category in webnotes.conn.sql_list("select name from `tabBlog Category` order by name") %} | |||
<li><a href="/blog?category={{ category }}">{{ category }}</a> | |||
{% endfor %} | |||
</ul> | |||
<br><br> | |||
{% endif %} | |||
<p>Show posts by <a href="/blog">everyone</a>. Meet the <a href="/writers">writers</a> of this blog</p> | |||
</p> | |||
</div> |
@@ -1,9 +0,0 @@ | |||
<h4>Subscribe</h4> | |||
<br> | |||
<p> | |||
<button class="btn btn-warning btn-blog-subscribe">Get Updates via Email</button> | |||
</p> | |||
<p> | |||
<img src="images/feed.png" style="margin-right: 4px; margin-bottom: -4px"> | |||
<a href="rss.xml" target="_blank">RSS Feed</a> | |||
</p> |
@@ -1,13 +1,13 @@ | |||
<div class="row"> | |||
<div class="col-md-2"> | |||
<div class="avatar avatar-large"> | |||
<img itemprop="thumbnailUrl" src="{{ blogger_info.avatar }}" /> | |||
<img itemprop="thumbnailUrl" src="{{ blogger_info.avatar | scrub_relative_url }}" /> | |||
</div> | |||
</div> | |||
<div class="col-md-10"> | |||
<h4>{{ blogger_info.full_name }}</h4> | |||
<p style="color: #999">{{ blogger_info.bio }}</p> | |||
<p><a href="blog?by={{ blogger_info.name }}&by_name={{ blogger_info.full_name }}"> | |||
<p><a href="/blog?by={{ blogger_info.name }}&by_name={{ blogger_info.full_name }}"> | |||
All Posts By {{ blogger_info.full_name }}</a></p> | |||
</div> | |||
</div> |
@@ -5,7 +5,7 @@ | |||
<div class="col-xs-9 web-footer-menu"> | |||
<ul class="list-inline"> | |||
{% for item in footer_items %} | |||
<li><a href="{{ item.url }}" {{ item.target }} | |||
<li><a href="{{ item.url | scrub_relative_url }}" {{ item.target }} | |||
data-label="{{ item.label }}">{{ item.label }}</a></li> | |||
{% endfor %} | |||
</ul> | |||
@@ -0,0 +1,57 @@ | |||
{% set post_url = "/" + post.website_group + "?view=post&name=" + post.name %} | |||
{% set edit_url = "/" + post.website_group + "?view=edit&name=" + post.name %} | |||
<div class="media post {% if post.parent_post -%} child-post {%- endif %}" | |||
data-name="{{ post.name }}" | |||
data-group="{{ post.website_group }}" | |||
itemscope itemtype="http://schema.org/Article"> | |||
<a class="pull-left media-link" href="{{ post_url }}"> | |||
<img class="media-object post-avatar" src="{{ post.user_image|scrub_relative_url }}"> | |||
</a> | |||
<div class="media-body"> | |||
{%- if not post.parent_post -%} | |||
<h4 class="media-heading" itemprop="headline"> | |||
{%- if view != "post" -%} | |||
<a class="no-decoration" | |||
href="{{ post_url }}">{{ post.title }}</a> | |||
{%- else -%} | |||
{{ post.title }} | |||
{%- endif -%} | |||
</h4> | |||
{%- endif -%} | |||
<ul class="list-inline small text-muted post-options"> | |||
{% if view_options and view_options.upvote %}<li class="upvote"> | |||
<a><span class="upvote-count {% if not post.upvotes %}hide{% endif %}">{{ post.upvotes }}</span> | |||
<i class="icon-thumbs-up"></i></a></li>{% endif %} | |||
{%- if not post.parent_post and view != "post" -%} | |||
<li><a itemprop="url" href="{{ post_url }}"> | |||
{% if not post.post_reply_count -%} | |||
<i class="icon-reply"></i> Reply | |||
{% elif post.post_reply_count == 1 %} | |||
{{ post.post_reply_count }} Reply | |||
{% else %} | |||
{{ post.post_reply_count }} Replies | |||
{%- endif %} | |||
</a></li> | |||
{%- endif -%} | |||
<li><span class="wn-timestamp" data-timestamp="{{ post.creation }}"></span></li> | |||
<li>by <span itemprop="author">{{ post.first_name or "" }} {{ post.last_name or "" }}</span></li> | |||
<li class="edit-post pull-right hide" data-owner="{{ post.owner }}"> | |||
<a class="text-muted" href="{{ edit_url }}">[edit]</a> | |||
</li> | |||
</ul> | |||
<div itemprop="articleBody" class="post-content"> | |||
{%- if post.is_task==1 and post.assigned_to -%} | |||
<span class="label label-info assigned-label"> | |||
<i class="icon-pencil"></i> {{ post.assigned_to_fullname }}</span> | |||
{%- elif post.is_event==1 and post.event_datetime -%} | |||
<span class="label label-info event-label"><i class="icon-calendar"></i> | |||
<span class="event-timestamp" data-timestamp="{{ post.event_datetime }}"></span></span> | |||
{%- endif -%} | |||
{{ post.content|markdown }} | |||
{%- if post.picture_url -%} | |||
<img src="{{ post.picture_url|scrub_relative_url }}" class="img-responsive post-picture" /> | |||
{%- endif -%} | |||
</div> | |||
</div> | |||
</div> |
@@ -68,11 +68,11 @@ login.do_login = function(){ | |||
window.location.href = "app"; | |||
} else if(data.message=="No App") { | |||
if(localStorage) { | |||
var last_visited = localStorage.getItem("last_visited") || "index"; | |||
var last_visited = localStorage.getItem("last_visited") || "/index"; | |||
localStorage.removeItem("last_visited"); | |||
window.location.href = last_visited; | |||
} else { | |||
window.location.href = "index"; | |||
window.location.href = "/index"; | |||
} | |||
} else if(window.is_sign_up) { | |||
wn.msgprint(data.message); | |||
@@ -9,7 +9,7 @@ | |||
<span class="icon-bar"></span> | |||
<span class="icon-bar"></span> | |||
</button> | |||
<a class="navbar-brand ellipsis" href="/index"> | |||
<a class="navbar-brand ellipsis" href="/"> | |||
<span>{{ brand_html or "<i class='icon-home'></i>"}}</span> | |||
</a> | |||
</div> | |||
@@ -19,7 +19,7 @@ | |||
{%- for page in top_bar_items -%} | |||
{% if not page.parent_label -%} | |||
<li data-label="{{ page.label }}" {% if page.child_items %} class="dropdown"{% endif %}> | |||
<a href="{{ page.url or '#' }}" {% if page.child_items %} class="dropdown-toggle" onclick="return false;" data-toggle="dropdown"{% endif %} {{ page.target or ''}}> | |||
<a href="{{ page.url | scrub_relative_url }}" {% if page.child_items %} class="dropdown-toggle" onclick="return false;" data-toggle="dropdown"{% endif %} {{ page.target or ''}}> | |||
{{ page.label }} | |||
{%- if page.child_items -%} | |||
<span class="caret"></span> | |||
@@ -28,7 +28,7 @@ | |||
{%- for child in page.child_items -%} | |||
<li data-label="{{ child.label }}"> | |||
<a {% if child.indent %} style="padding-left: {{((child.indent|int)+1)*15 }}px"{% endif %} | |||
href="{{ child.url }}" {{ child.target or '' }}>{{ child.label }}</a> | |||
href="{{ child.url | scrub_relative_url }}" {{ child.target or '' }}>{{ child.label }}</a> | |||
</li> | |||
{%- endfor -%} | |||
</ul> | |||
@@ -53,7 +53,7 @@ | |||
{% if child.class %} class="{{ child.class }}" {% endif %}> | |||
{%- if child.url -%} | |||
<a href="{{ child.url }}" {{ child.target or '' }}> | |||
<a href="{{ child.url | scrub_relative_url }}" {{ child.target or '' }}> | |||
{%- if child.icon -%} | |||
<i class="icon-fixed-width {{ child.icon }}"></i> | |||
{%- endif -%} | |||
@@ -77,6 +77,6 @@ | |||
</ul> | |||
</div> | |||
</div> | |||
</div> | |||
</nav> | |||
</header> | |||
<script>$('.dropdown-toggle').dropdown()</script> |
@@ -0,0 +1,11 @@ | |||
{% if posts %} | |||
{% for post in posts %} | |||
{% include "templates/includes/inline_post.html" %} | |||
{% endfor %} | |||
{% else %} | |||
{% if limit_start %} | |||
<div class="no-posts alert alert-info">No more posts.</div> | |||
{% else %} | |||
<div class="no-posts alert alert-info">Nothing posted yet.</div> | |||
{% endif %} | |||
{% endif %} |
@@ -0,0 +1,12 @@ | |||
{%- if children -%} | |||
{%- for child in children -%} | |||
<div class="sidebar-item"> | |||
<a href="/{{ child.url|lower }}"> | |||
{{ child.page_title }} | |||
{% if not child.public_read %} | |||
(<i class="icon-fixed-width icon-lock"></i>) | |||
{% endif %} | |||
</a> | |||
</div> | |||
{%- endfor -%} | |||
{%- endif -%} |
@@ -15,7 +15,7 @@ | |||
<div class="carousel-inner"> | |||
{% for slide in obj.slides %} | |||
<div class="{% if slide.idx==1 %}active {% endif %}item"> | |||
<img src="{{ slide.image }}" class="slide-image" /> | |||
<img src="{{ slide.image | scrub_relative_url }}" class="slide-image" /> | |||
{% if slide.heading or slide.description %} | |||
<div class="carousel-caption"> | |||
{% if slide.heading %}<h4>{{ slide.heading }}</h4>{% endif %} | |||
@@ -1,13 +1,12 @@ | |||
{% extends base_template %} | |||
{%- block title -%}Not Found{%- endblock -%} | |||
{% set title="Not Found" %} | |||
{%- block header -%} | |||
<h2 class="text-danger"><i class="icon-exclamation-sign"></i> Page missing or moved</h2> | |||
{%- endblock -%} | |||
{% block content %} | |||
<div class="container content panel-container"> | |||
<div class="panel panel-danger"> | |||
<div class="panel-heading"> | |||
<i class="icon-exclamation-sign"></i> Page missing or moved | |||
</div> | |||
<div class="404-content"> | |||
<div class="panel panel-default"> | |||
<div class="panel-body"> | |||
<p>We are very sorry for this, but the page you are looking for is missing | |||
(this could be because of a typo in the address) or moved.</p> | |||
@@ -0,0 +1,12 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.webutils import render_blocks | |||
no_sitemap = 1 | |||
def get_context(context): | |||
return render_blocks(context) |
@@ -1,10 +1,17 @@ | |||
{% extends base_template %} | |||
{% block title %} About Us {% endblock %} | |||
{% set title="About Us" %} | |||
{% block header %}<h2>About Us</h2>{% endblock %} | |||
{% block content %} | |||
<div class="container content"> | |||
{{ obj.doc.company_introduction or "<h2>About Us</h2><p>Some Introduction about your company that you would like your website visitor to know. More people than you think will read your About page. People always like to know who the are doing business with. Be authentic and avoid using jargon like 'value added services' etc. Be sure to update your company history and list of key team members in Website > About Us Settings</p>" }} | |||
<div class="about-content"> | |||
{{ obj.doc.company_introduction or """<p>Some Introduction about your company that you would | |||
like your website visitor to know. | |||
More people than you think will read your About page. | |||
People always like to know who the are doing business with. | |||
Be authentic and avoid using jargon like 'value added services' etc. | |||
Be sure to update your company history and | |||
list of key team members in Website > About Us Settings</p>""" }} | |||
{% if obj.doclist.get({"doctype":"Company History"}) %} | |||
<h3>{{ obj.doc.company_history_heading or "Company History" }}</h3> | |||
{% for d in obj.doclist.get({"doctype":"Company History"}) %} | |||
@@ -14,6 +21,7 @@ | |||
</div> | |||
{% endfor %} | |||
{% endif %} | |||
{% if obj.doclist.get({"doctype":"About Us Team Member"}) %} | |||
<h3>{{ obj.doc.team_members_heading or "Team Members" }}</h3> | |||
{% for d in obj.doclist.get({"doctype":"About Us Team Member"}) %} | |||
@@ -31,4 +39,4 @@ | |||
{% endif %} | |||
{{ obj.doc.footer or "" }} | |||
</div> | |||
{% endblock %} | |||
{% endblock %} |
@@ -3,8 +3,12 @@ | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.webutils import render_blocks | |||
def get_context(): | |||
return { | |||
def get_context(context): | |||
about_context = { | |||
"obj": webnotes.bean("About Us Settings", "About Us Settings").get_controller() | |||
} | |||
} | |||
about_context.update(context) | |||
return render_blocks(about_context) |
@@ -1,6 +1,9 @@ | |||
{% block title %}{{ blog_title or "Blog" }}{% endblock %} | |||
{% block header %}<h2>{{ blog_title or "Blog" }}</h2>{% endblock %} | |||
{% block content %} | |||
<div class="container content"> | |||
<h2 id="blog-title">{{ blog_title }}</h2> | |||
<div class="blog-list-content"> | |||
{% if blog_introduction %} | |||
<p>{{ blog_introduction }}</p> | |||
{% endif %} | |||
@@ -17,8 +20,11 @@ | |||
style="display:none;">More...</button> | |||
</div> | |||
</div> | |||
{% include 'templates/includes/blog_footer.html' %} | |||
<script> | |||
{% include "templates/includes/blog.js" %} | |||
</script> | |||
{% endblock %} | |||
{% endblock %} | |||
{% block footer %}{% include 'templates/includes/blog_footer.html' %}{% endblock %} | |||
{% block sidebar %}{% include "templates/includes/sidebar.html" %}{% endblock %} |
@@ -3,13 +3,9 @@ | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes import _ | |||
from webnotes.webutils import render_blocks | |||
def get_context(context): | |||
extended_context = webnotes.doc("Blog Settings", "Blog Settings").fields | |||
extended_context.update(context) | |||
return { | |||
"title": extended_context.blog_title or "Blog", | |||
"content": context.template.render(extended_context) | |||
} | |||
blog_context = webnotes.doc("Blog Settings", "Blog Settings").fields | |||
blog_context.update(context) | |||
return render_blocks(blog_context) |
@@ -1,16 +1,9 @@ | |||
{% extends base_template %} | |||
{% block title %}{{ heading or "Contact Us"}}{% endblock %} | |||
{% block javascript %} | |||
<script> | |||
{% include "templates/includes/contact.js" %} | |||
</script> | |||
{% endblock %} | |||
{% set title="Contact Us" %} | |||
{% block header %}<h2>{{ heading or "Contact Us"}}</h2>{% endblock %} | |||
{% block content %} | |||
<div class="container content"> | |||
<h3>{{ heading or "Contact Us"}}</h3> | |||
<div class="contact-content"> | |||
<div class="row"> | |||
<div class="col-md-8"> | |||
<p id="contact-alert" class="alert alert-warning" | |||
@@ -62,6 +55,9 @@ | |||
</div> | |||
{% endif %} | |||
</div> | |||
{{ introduction }} | |||
{{ introduction or ""}} | |||
</div> | |||
<script> | |||
{% include "templates/includes/contact.js" %} | |||
</script> | |||
{% endblock %} |
@@ -5,8 +5,9 @@ from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.utils import now | |||
from webnotes.webutils import render_blocks | |||
def get_context(): | |||
def get_context(context): | |||
bean = webnotes.bean("Contact Us Settings", "Contact Us Settings") | |||
query_options = filter(None, bean.doc.query_options.replace(",", "\n").split()) if \ | |||
@@ -14,13 +15,15 @@ def get_context(): | |||
address = webnotes.bean("Address", bean.doc.address).doc if bean.doc.address else None | |||
return { | |||
contact_context = { | |||
"query_options": query_options, | |||
"address": address, | |||
"heading": bean.doc.heading, | |||
"introduction": bean.doc.introduction | |||
} | |||
contact_context.update(context) | |||
return render_blocks(context) | |||
max_communications_per_hour = 300 | |||
@@ -1,16 +1,13 @@ | |||
{% extends base_template %} | |||
{% block title %}Error{% endblock %} | |||
{% set title="Error" %} | |||
{% block header %} | |||
<h2 class="text-danger"> | |||
<i class="icon-exclamation-sign"></i> Oops, a server error has occured | |||
</h2> | |||
{% endblock %} | |||
{% block content %} | |||
<div class="container content panel-container"> | |||
<div class="panel panel-danger"> | |||
<div class="panel-heading"> | |||
<i class="icon-exclamation-sign"></i> Oops, a server error has occured | |||
</div> | |||
<div class="panel-body"> | |||
<pre>%(error)s</pre> | |||
</div> | |||
</div> | |||
<div class="error-content"> | |||
<pre>%(error)s</pre> | |||
</div> | |||
{% endblock %} |
@@ -2,6 +2,11 @@ | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.webutils import render_blocks | |||
no_cache = 1 | |||
no_sitemap = 1 | |||
no_sitemap = 1 | |||
def get_context(context): | |||
return render_blocks(context) |
@@ -1,5 +1,7 @@ | |||
{% block title %} Login {% endblock %} | |||
{% block content %} | |||
<div class="container content" style="max-width: 800px;"> | |||
<div class="login-content container" style="max-width: 800px;"> | |||
<div class="row" style="margin-top: 70px; margin-bottom: 20px"> | |||
<div class="col-sm-offset-1 col-sm-10"> | |||
<div class="panel panel-default"> | |||
@@ -1,7 +1,5 @@ | |||
import webnotes | |||
from webnotes.webutils import render_blocks | |||
def get_context(context): | |||
return { | |||
"title": webnotes._("Login"), | |||
"content": context.template.render(context) | |||
} | |||
return render_blocks(context) |
@@ -1,15 +1,12 @@ | |||
{% extends base_template %} | |||
{% block title %}{{ title }}{% endblock %} | |||
{% set title=webnotes.local.message_title %} | |||
{% block header %}<h2 class="text-{{ 'success' if success else 'danger'}}">{{ title }}</h2>{% endblock %} | |||
{% block content %} | |||
<div class="container content panel-container"> | |||
<div class="panel panel-{{ 'success' if webnotes.local.message_success else 'danger'}}"> | |||
<div class="panel-heading"> | |||
{{ title }} | |||
</div> | |||
<div class="message-content"> | |||
<div class="panel panel-default"> | |||
<div class="panel-body"> | |||
<p>{{ webnotes.local.message }}</p> | |||
<p>{{ message }}</p> | |||
</div> | |||
</div> | |||
</div> |
@@ -2,6 +2,18 @@ | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.webutils import render_blocks | |||
no_cache = 1 | |||
no_sitemap = 1 | |||
no_sitemap = 1 | |||
def get_context(context): | |||
message_context = {} | |||
if hasattr(webnotes.local, "message"): | |||
message_context["title"] = webnotes.local.message_title | |||
message_context["message"] = webnotes.local.message | |||
message_context["success"] = webnotes.local.message_success | |||
message_context.update(context) | |||
return render_blocks(message_context) |
@@ -5,7 +5,8 @@ from __future__ import unicode_literals | |||
no_cache = 1 | |||
no_sitemap = 1 | |||
base_template_path = "templates/pages/print.html" | |||
def get_context(): | |||
def get_context(context): | |||
from webnotes.core.doctype.print_format.print_format import get_args | |||
return get_args() |
@@ -7,8 +7,9 @@ import os, urllib | |||
from webnotes.utils import escape_html, get_request_site_address, now, cstr | |||
no_cache = 1 | |||
base_template_path = "templates/pages/rss.xml" | |||
def get_context(): | |||
def get_context(context): | |||
"""generate rss feed""" | |||
host = get_request_site_address() | |||
@@ -19,7 +20,8 @@ def get_context(): | |||
order by published_on desc limit 20""", as_dict=1) | |||
for blog in blog_list: | |||
blog.link = cstr(urllib.quote((host + '/' + blog.name + '.html').encode("utf-8"))) | |||
blog_page = cstr(urllib.quote(blog.name.encode("utf-8"))) + ".html" | |||
blog.link = urllib.basejoin(host, blog_page) | |||
blog.content = escape_html(blog.content or "") | |||
if blog_list: | |||
@@ -10,8 +10,9 @@ from webnotes.utils import get_request_site_address | |||
no_cache = 1 | |||
no_sitemap = 1 | |||
base_template_path = "templates/pages/sitemap.xml" | |||
def get_context(): | |||
def get_context(context): | |||
"""generate the sitemap XML""" | |||
host = get_request_site_address() | |||
links = [] | |||
@@ -3,9 +3,11 @@ | |||
from __future__ import unicode_literals | |||
import webnotes | |||
no_sitemap = True | |||
def get_context(): | |||
no_sitemap = 1 | |||
base_template_path = "templates/pages/style_settings.css" | |||
def get_context(context): | |||
"""returns web style""" | |||
from webnotes.webutils import get_hex_shade | |||
@@ -1,4 +1,4 @@ | |||
{% extends base_template %} | |||
{% block title %} Reset Password {% endblock %} | |||
{% block content %} | |||
<div class="container"> | |||
@@ -2,5 +2,9 @@ | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
from webnotes.webutils import render_blocks | |||
no_sitemap = True | |||
no_sitemap = 1 | |||
def get_context(context): | |||
return render_blocks(context) |
@@ -4,9 +4,10 @@ | |||
from __future__ import unicode_literals | |||
import webnotes | |||
no_sitemap = True | |||
no_sitemap = 1 | |||
base_template_path = "templates/pages/website_script.js" | |||
def get_context(): | |||
def get_context(context): | |||
return { | |||
"javascript": webnotes.conn.get_value('Website Script', None, 'javascript'), | |||
"google_analytics_id": webnotes.conn.get_value("Website Settings", "Website Settings", "google_analytics_id") |
@@ -1,18 +1,19 @@ | |||
{% extends base_template %} | |||
{% block title %} Blog Writers {% endblock %} | |||
{% set title="Blog Writers" %} | |||
{% block header %}<h2>Blog Writers</h2>{% endblock %} | |||
{% block content %} | |||
<div class="container content"> | |||
<h2 id="blog-title">Blog Writers</h2> | |||
<div class="writers-content"> | |||
{% if writers_introduction %} | |||
<p>{{ writers_introduction }}</p> | |||
{% endif %} | |||
<hr> | |||
{% for blogger_info in bloggers %} | |||
{% include "templates/includes/blogger.html" %} | |||
{% if not loop.last %}<hr>{% endif %} | |||
{% endfor %} | |||
</div> | |||
{% include 'templates/includes/blog_footer.html' %} | |||
{% endblock %} | |||
{% endblock %} | |||
{% block footer %}{% include "templates/includes/blog_footer.html" %}{% endblock %} | |||
{% block sidebar %}{% include "templates/includes/sidebar.html" %}{% endblock %} |
@@ -3,13 +3,14 @@ | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.webutils import render_blocks | |||
def get_context(): | |||
def get_context(context): | |||
bloggers = webnotes.conn.sql("""select * from `tabBlogger` | |||
where ifnull(posts,0) > 0 and ifnull(disabled,0)=0 | |||
order by posts desc""", as_dict=1) | |||
args = { | |||
writers_context = { | |||
"bloggers": bloggers, | |||
"texts": { | |||
"all_posts_by": "All posts by" | |||
@@ -17,5 +18,7 @@ def get_context(): | |||
"categories": webnotes.conn.sql_list("select name from `tabBlog Category` order by name") | |||
} | |||
args.update(webnotes.doc("Blog Settings", "Blog Settings").fields) | |||
return args | |||
writers_context.update(webnotes.doc("Blog Settings", "Blog Settings").fields) | |||
writers_context.update(context) | |||
return render_blocks(writers_context) |
@@ -0,0 +1,22 @@ | |||
{%- block view -%} | |||
<div class="small text-muted post-list-help"></div> | |||
<div class="post-list"> | |||
{{ post_list_html }} | |||
</div> | |||
<div class="text-center"> | |||
<button class="btn btn-default btn-more hide">More</button> | |||
</div> | |||
{%- endblock -%} | |||
{%- block group_script -%} | |||
<script> | |||
$(function() { | |||
app.setup_more_btn({ | |||
cmd: "webnotes.templates.website_group.forum.get_post_list_html" | |||
}); | |||
app.toggle_edit(true); | |||
app.setup_upvote(); | |||
app.toggle_upvote(); | |||
}); | |||
</script> | |||
{%- endblock -%} |
@@ -0,0 +1,109 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import webnotes | |||
from webnotes.utils import now_datetime, get_datetime_str | |||
from webnotes.webutils import get_access | |||
from webnotes.templates.generators.website_group import get_views | |||
def get_views(): | |||
return views | |||
def get_context(group_context): | |||
return { | |||
"post_list_html": get_post_list_html(group_context["group"]["name"], group_context["view"]) | |||
} | |||
@webnotes.whitelist(allow_guest=True) | |||
def get_post_list_html(group, view, limit_start=0, limit_length=20): | |||
access = get_access(group) | |||
if isinstance(view, basestring): | |||
view = get_views(group)["view"] | |||
view = webnotes._dict(view) | |||
# verify permission for paging | |||
if webnotes.local.form_dict.cmd == "get_post_list_html": | |||
if not access.get("read"): | |||
return webnotes.PermissionError | |||
if view.name == "feed": | |||
order_by = "p.creation desc" | |||
else: | |||
now = get_datetime_str(now_datetime()) | |||
order_by = """(p.upvotes + post_reply_count - (timestampdiff(hour, p.creation, \"{}\") / 2)) desc, | |||
p.creation desc""".format(now) | |||
posts = webnotes.conn.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, `tabProfile` pr | |||
where p.website_group = %s and pr.name = p.owner and ifnull(p.parent_post, '')='' | |||
order by {order_by} limit %s, %s""".format(order_by=order_by), | |||
(group, int(limit_start), int(limit_length)), as_dict=True) | |||
context = {"posts": posts, "limit_start": limit_start, "view": view} | |||
return webnotes.get_template("templates/includes/post_list.html").render(context) | |||
views = { | |||
"popular": { | |||
"name": "popular", | |||
"template_path": "templates/unit_templates/forum_list.html", | |||
"url": "/{group}", | |||
"label": "Popular", | |||
"icon": "icon-heart", | |||
"default": True, | |||
"upvote": True, | |||
"idx": 1 | |||
}, | |||
"feed": { | |||
"name": "feed", | |||
"template_path": "templates/unit_templates/forum_list.html", | |||
"url": "/{group}?view=feed", | |||
"label": "Feed", | |||
"icon": "icon-rss", | |||
"upvote": True, | |||
"idx": 2 | |||
}, | |||
"post": { | |||
"name": "post", | |||
"template_path": "templates/unit_templates/base_post.html", | |||
"url": "/{group}?view=post&name={post}", | |||
"label": "Post", | |||
"icon": "icon-comments", | |||
"upvote": True, | |||
"hidden": True, | |||
"no_cache": True, | |||
"idx": 3 | |||
}, | |||
"edit": { | |||
"name": "edit", | |||
"template_path": "templates/unit_templates/base_edit.html", | |||
"url": "/{group}?view=edit&name={post}", | |||
"label": "Edit Post", | |||
"icon": "icon-pencil", | |||
"hidden": True, | |||
"no_cache": True, | |||
"idx": 4 | |||
}, | |||
"add": { | |||
"name": "add", | |||
"template_path": "templates/unit_templates/base_edit.html", | |||
"url": "/{group}?view=add", | |||
"label": "Add Post", | |||
"icon": "icon-plus", | |||
"hidden": True, | |||
"idx": 5 | |||
}, | |||
"settings": { | |||
"name": "settings", | |||
"template_path": "templates/unit_templates/base_settings.html", | |||
"url": "/{group}&view=settings", | |||
"label": "Settings", | |||
"icon": "icon-cog", | |||
"hidden": True, | |||
"idx": 6 | |||
} | |||
} |
@@ -48,8 +48,7 @@ img { | |||
} | |||
.web-footer { | |||
margin-top: 10px; | |||
padding-bottom: 20px; | |||
padding: 20px 0px; | |||
} | |||
.avatar { | |||
@@ -158,7 +157,7 @@ img { | |||
.navbar { | |||
box-shadow: none; | |||
border-radius: 0px; | |||
margin-bottom: 7px; | |||
margin-bottom: 0px; | |||
} | |||
.navbar-brand { | |||
@@ -210,4 +209,93 @@ fieldset { | |||
.slide-image { | |||
width: 100%; | |||
} | |||
.page-header { | |||
margin: 0 0 20px; | |||
padding: 5px 0px; | |||
} | |||
.page-header h1, | |||
.page-header h2, | |||
.page-header h3 { | |||
margin-top: 5px; | |||
} | |||
.page-header .lead { | |||
margin-bottom: 5px; | |||
} | |||
.page-sidebar { | |||
border-left: 1px solid #aaa; | |||
} | |||
html, | |||
body { | |||
height: 100%; | |||
/* The html and body elements cannot have any padding or margin. */ | |||
} | |||
/* Wrapper for page content to push down footer */ | |||
#wrap { | |||
min-height: 100%; | |||
height: auto; | |||
/* Negative indent footer by its height */ | |||
margin: auto; | |||
margin: 0 auto -140px; | |||
/* Pad bottom by footer height */ | |||
padding: 0 0 140px; | |||
} | |||
/* Set the fixed height of the footer here */ | |||
#footer { | |||
height: 140px; | |||
background-color: #f5f5f5; | |||
} | |||
.page-footer { | |||
margin: 20px 0px 0px; | |||
border-top: 1px solid #eee; | |||
} | |||
/* website group */ | |||
.view-selector { | |||
margin-bottom: 15px; | |||
} | |||
/* post and post list */ | |||
.post { | |||
padding: 7px 0px; | |||
word-wrap: break-word; | |||
border-bottom: 1px solid #eee; | |||
} | |||
.post .img-responsive { | |||
border-radius: 4px; | |||
} | |||
.post .media-link { | |||
display: block; | |||
min-width: 50px; | |||
min-height: 50px; | |||
} | |||
.post .media-object { | |||
border-radius: 4px; | |||
} | |||
.post .media-heading { | |||
margin-bottom: 12px; | |||
} | |||
.parent-post .post { | |||
border: none; | |||
} | |||
.child-post { | |||
border: 1px solid #eee; | |||
padding-left: 15px; | |||
background-color: #f8f8f8; | |||
margin-top: 0px; | |||
} |
@@ -37,81 +37,3 @@ class DocType(WebsiteGenerator): | |||
if self.doclist.get({"parentfield": "toc"}): | |||
from webnotes.webutils import clear_cache | |||
clear_cache() | |||
def get_context(self): | |||
if self.doc.slideshow: | |||
from webnotes.website.doctype.website_slideshow.website_slideshow import get_slideshow | |||
get_slideshow(self) | |||
self.doc.meta_description = self.doc.description | |||
self.doc.breadcrumbs = self.get_breadcrumbs() | |||
self.doc.toc_list = self.get_toc_list() | |||
# parent, child, next sibling links | |||
self.doc.links = self.get_navigation_links() | |||
if self.doc.enable_comments: | |||
self.doc.comment_list = webnotes.conn.sql("""select | |||
comment, comment_by_fullname, creation | |||
from `tabComment` where comment_doctype="Web Page" | |||
and comment_docname=%s order by creation""", self.doc.name, as_dict=1) or [] | |||
def get_breadcrumbs(self): | |||
breadcrumbs = [] | |||
def add_parent_of(web_page): | |||
parent = webnotes.conn.sql("""select name, page_name, title from `tabWeb Page` | |||
where exists (select parent from `tabTable of Contents` | |||
where `tabTable of Contents`.parent=`tabWeb Page`.name | |||
and web_page=%s)""", web_page, as_dict=True) | |||
if parent and parent[0]: | |||
parent = parent[0] | |||
add_parent_of(parent.name) | |||
breadcrumbs.append(parent) | |||
add_parent_of(self.doc.name) | |||
return breadcrumbs | |||
def get_toc_list(self): | |||
toc_list = self.doclist.get({"parentfield": "toc"}) | |||
if not toc_list: return [] | |||
out = webnotes.conn.sql("""select name, page_name, title | |||
from `tabWeb Page` where name in (%s)""" % \ | |||
(", ".join(["%s"]*len(toc_list))), | |||
tuple([d.web_page for d in toc_list]), | |||
as_dict=True) | |||
toc_idx = dict(((toc.web_page, toc.idx) for toc in toc_list)) | |||
return sorted(out, key=lambda x: toc_idx.get(x.name)) | |||
def get_navigation_links(self): | |||
links = {} | |||
if self.doc.toc_list: | |||
links["child"] = self.doc.toc_list[0] | |||
if self.doc.breadcrumbs: | |||
if self.doc.breadcrumbs[-1]: | |||
links["parent"] = self.doc.breadcrumbs[-1] | |||
def set_next(current, parent, breadcrumbs): | |||
web_page = webnotes.get_obj("Web Page", parent) | |||
toc_list = web_page.get_toc_list() | |||
for i, toc in enumerate(toc_list): | |||
if toc.name == current and ((i+1)<len(toc_list)): | |||
links["next"] = toc_list[i+1] | |||
break | |||
if not links.get("next") and breadcrumbs: | |||
set_next(parent, breadcrumbs[-1].name, breadcrumbs[:-1]) | |||
set_next(self.doc.name, self.doc.breadcrumbs[-1].name, self.doc.breadcrumbs[:-1]) | |||
return links | |||
@@ -27,6 +27,3 @@ class DocType(WebsiteGenerator): | |||
if not self.doc.page_name: | |||
webnotes.throw(_("Page Name is mandatory"), raise_exception=webnotes.MandatoryError) | |||
def get_context(self, page_options): | |||
return get_context(self, page_options) |
@@ -304,5 +304,12 @@ $(document).ready(function() { | |||
$("#website-post-login .dropdown-menu").append('<li class="divider"></li>\ | |||
<li><a href="app.html"><i class="icon-fixed-width icon-th-large"></i> Switch To App</a></li>'); | |||
} | |||
$(document).trigger("page_change"); | |||
}); | |||
$(document).on("page_change", function() { | |||
$(".page-header").toggleClass("hidden", !!!$(".page-header").text().trim()); | |||
$(".page-footer").toggleClass("hidden", !!!$(".page-footer").text().trim()); | |||
}); | |||
@@ -75,8 +75,7 @@ def build_page(page_name): | |||
context = get_context(page_name) | |||
context.update(get_website_settings()) | |||
jenv = webnotes.get_jenv() | |||
html = jenv.get_template(context.base_template_path).render(context) | |||
html = webnotes.get_template(context.base_template_path).render(context) | |||
if can_cache(context.no_cache): | |||
webnotes.cache().set_value("page:" + page_name, html) | |||
@@ -92,7 +91,7 @@ def get_context(page_name): | |||
context = webnotes.cache().get_value(cache_key) | |||
if not context: | |||
sitemap_options = build_sitemap_options(page_name) | |||
sitemap_options = get_sitemap_options(page_name) | |||
context = build_context(sitemap_options) | |||
if can_cache(context.no_cache): | |||
webnotes.cache().set_value(cache_key, context) | |||
@@ -100,6 +99,21 @@ def get_context(page_name): | |||
context.update(context.data or {}) | |||
return context | |||
def get_sitemap_options(page_name): | |||
sitemap_options = None | |||
cache_key = "sitemap_options:{}".format(page_name) | |||
if can_cache(): | |||
sitemap_options = webnotes.cache().get_value(cache_key) | |||
if sitemap_options: | |||
return sitemap_options | |||
sitemap_options = build_sitemap_options(page_name) | |||
if can_cache(sitemap_options.no_cache): | |||
webnotes.cache().set_value(cache_key, sitemap_options) | |||
return sitemap_options | |||
def build_sitemap_options(page_name): | |||
sitemap_options = webnotes.doc("Website Sitemap", page_name).fields | |||
@@ -121,7 +135,7 @@ def build_sitemap_options(page_name): | |||
where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True) | |||
sitemap_options.children = webnotes.conn.sql("""select * from `tabWebsite Sitemap` | |||
where parent_website_sitemap=%s""", (sitemap_options.page_name,)) | |||
where parent_website_sitemap=%s""", (sitemap_options.page_name,), as_dict=True) | |||
# determine templates to be used | |||
if not sitemap_options.base_template_path: | |||
@@ -199,7 +213,7 @@ def get_website_settings(): | |||
"disable_signup"]: | |||
context[k] = cint(context.get(k) or 0) | |||
context.url = quote(str(get_request_site_address(full_address=True)), str("")) | |||
context.url = quote(str(get_request_site_address(full_address=True)), safe="/:") | |||
context.encoded_title = quote(encode(context.title or ""), str("")) | |||
for update_website_context in hooks.update_website_context or []: | |||
@@ -226,10 +240,11 @@ def scrub_page_name(page_name): | |||
return page_name | |||
def insert_traceback(data): | |||
traceback = webnotes.get_traceback() | |||
if isinstance(data, dict): | |||
data["error"] = webnotes.get_traceback() | |||
data["error"] = traceback | |||
else: | |||
data = data.replace("%(error)s", webnotes.get_traceback()) | |||
data = data % {"error": traceback} | |||
return data | |||
@@ -391,5 +406,17 @@ def get_hex_shade(color, percent): | |||
return p(r) + p(g) + p(b) | |||
def get_access(sitemap): | |||
pass | |||
def render_blocks(context): | |||
"""returns a dict of block name and its rendered content""" | |||
from jinja2.utils import concat | |||
out = {} | |||
template = context["template"] | |||
# required as per low level API | |||
context = template.new_context(context) | |||
# render each block individually | |||
for block, render in template.blocks.items(): | |||
out[block] = concat(render(context)) | |||
return out |