Merge pull request #1493 from rmehta/load-js-after-html

[website] load js after html
This commit is contained in:
Anand Doshi 2016-01-04 11:40:40 +05:30
commit 33d45b4e52
40 changed files with 344 additions and 933 deletions

View file

@ -64,22 +64,6 @@
<p class="docs-attr-name">
<a name="frappe.website.render.build_json" href="#frappe.website.render.build_json" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
frappe.website.render.<b>build_json</b>
<i class="text-muted">(path)</i>
</p>
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
</div>
<br>
<p class="docs-attr-name">
<a name="frappe.website.render.build_page" href="#frappe.website.render.build_page" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
@ -144,22 +128,6 @@
<p class="docs-attr-name">
<a name="frappe.website.render.is_ajax" href="#frappe.website.render.is_ajax" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
frappe.website.render.<b>is_ajax</b>
<i class="text-muted">()</i>
</p>
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
</div>
<br>
<p class="docs-attr-name">
<a name="frappe.website.render.render" href="#frappe.website.render.render" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>

View file

@ -114,22 +114,6 @@ Hero elements get full page width.</p>
<p class="docs-attr-name">
<a name="frappe.website.template.set_sidebar" href="#frappe.website.template.set_sidebar" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
frappe.website.template.<b>set_sidebar</b>
<i class="text-muted">(out, context)</i>
</p>
<div class="docs-attr-desc"><p>Include sidebar (deprecated)</p>
</div>
<br>
<p class="docs-attr-name">
<a name="frappe.website.template.set_title_and_header" href="#frappe.website.template.set_title_and_header" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>

View file

@ -1595,6 +1595,8 @@ The mentions will be separated by non-word characters or may appear at the start

View file

@ -423,6 +423,35 @@ Right</pre>
<p class="docs-attr-name">
<a name="add_hero" href="#add_hero" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
<b>add_hero</b>
<i class="text-muted">(self, context)</i>
</p>
<div class="docs-attr-desc"><p>Add a hero element if specified in content or hooks.
Hero elements get full page width.</p>
</div>
<br>
<p class="docs-attr-name">
<a name="add_index" href="#add_index" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
<b>add_index</b>
<i class="text-muted">(self, context)</i>
</p>
<div class="docs-attr-desc"><p>Add index, next button if <code>{index}</code>, <code>{next}</code> is present.</p>
</div>
<br>
<p class="docs-attr-name">
<a name="check_for_redirect" href="#check_for_redirect" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
@ -507,6 +536,20 @@ Right</pre>
<p class="docs-attr-name">
<a name="set_breadcrumbs" href="#set_breadcrumbs" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
<b>set_breadcrumbs</b>
<i class="text-muted">(self, context)</i>
</p>
<div class="docs-attr-desc"><p>Build breadcrumbs template (deprecated)</p>
</div>
<br>
<p class="docs-attr-name">
<a name="set_metatags" href="#set_metatags" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
@ -521,6 +564,20 @@ Right</pre>
<p class="docs-attr-name">
<a name="set_title_and_header" href="#set_title_and_header" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>
<b>set_title_and_header</b>
<i class="text-muted">(self, context)</i>
</p>
<div class="docs-attr-desc"><p>Extract and set title and header from content or context.</p>
</div>
<br>
<p class="docs-attr-name">
<a name="validate" href="#validate" class="text-muted small">
<i class="icon-link small" style="color: #ccc;"></i></a>

View file

@ -45,12 +45,6 @@ website_route_rules = [
{"from_route": "/blog/<category>", "to_route": "Blog Post"}
]
website_context = {
"hero": {
"blog": "templates/includes/blog/hero.html"
}
}
write_file_keys = ["file_url", "file_name"]
notification_config = "frappe.core.notifications.get_notification_config"

View file

@ -2,14 +2,12 @@
"css/frappe-web.css": [
"public/css/font-awesome.css",
"public/css/octicons/octicons.css",
"public/css/nprogress.css",
"public/css/website.css"
],
"js/frappe-web.min.js": [
"public/js/lib/bootstrap.min.js",
"public/js/frappe/provide.js",
"public/js/frappe/misc/number_format.js",
"public/js/lib/nprogress.js",
"public/js/frappe/translate.js",
"public/js/frappe/misc/pretty_date.js",
"public/js/lib/moment/moment.min.js",
@ -39,7 +37,6 @@
"public/css/sidebar.css",
"public/css/page.css",
"public/css/tree.css",
"public/css/nprogress.css",
"public/css/desktop.css",
"public/css/form.css",
"public/css/mobile.css"
@ -50,7 +47,6 @@
"public/js/lib/tag-it.min.js",
"public/js/lib/notify.js",
"public/js/lib/bootstrap.min.js",
"public/js/lib/nprogress.js",
"public/js/lib/moment/moment-with-locales.min.js",
"public/js/lib/moment/moment-timezone-with-data.min.js",
"public/js/lib/socket.io.min.js",

View file

@ -1,85 +0,0 @@
/* Make clicks pass-through */
#nprogress {
pointer-events: none;
-webkit-pointer-events: none;
}
/* Make the entire page show a busy cursor */
.nprogress-busy body {
cursor: wait;
}
#nprogress .bar {
background: #36414C;
position: fixed;
z-index: 1050;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
/* Fancy blur effect */
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
/*box-shadow: 0 0 10px #2ecc71, 0 0 5px #2ecc71;*/
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-moz-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
-o-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
/* Remove these to get rid of the spinner
#nprogress .spinner {
display: block;
position: fixed;
z-index: 1050;
top: 7px;
right: 15px;
}
#nprogress .spinner-icon {
width: 14px;
height: 14px;
border: solid 2px transparent;
border-top-color: #fff;
border-left-color: #fff;
border-radius: 10px;
-webkit-animation: nprogress-spinner 400ms linear infinite;
-moz-animation: nprogress-spinner 400ms linear infinite;
-ms-animation: nprogress-spinner 400ms linear infinite;
-o-animation: nprogress-spinner 400ms linear infinite;
animation: nprogress-spinner 400ms linear infinite;
}
@-webkit-keyframes nprogress-spinner {
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}
@-moz-keyframes nprogress-spinner {
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
}
@-o-keyframes nprogress-spinner {
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
}
@-ms-keyframes nprogress-spinner {
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
}
@keyframes nprogress-spinner {
0% { transform: rotate(0deg); transform: rotate(0deg); }
100% { transform: rotate(360deg); transform: rotate(360deg); }
}*/

View file

@ -1,220 +0,0 @@
/*! NProgress (c) 2013, Rico Sta. Cruz
* http://ricostacruz.com/nprogress */
;(function(factory) {
if (typeof module === 'object') {
module.exports = factory(this.jQuery || require('dom'));
} else {
this.NProgress = factory(this.jQuery);
}
})(function($) {
var NProgress = {};
NProgress.version = '0.1.0';
var Settings = NProgress.settings = {
minimum: 0.08,
easing: 'ease',
speed: 200,
trickle: true,
trickleRate: 0.02,
trickleSpeed: 800,
template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner"><div class="spinner-icon"></div></div>'
};
/**
* Updates configuration.
*
* NProgress.configure({
* minimum: 0.1
* });
*/
NProgress.configure = function(options) {
$.extend(Settings, options);
return this;
};
/**
* Last number.
*/
NProgress.status = null;
/**
* Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
*
* NProgress.set(0.4);
* NProgress.set(1.0);
*/
NProgress.set = function(n) {
var started = NProgress.isStarted();
n = clamp(n, Settings.minimum, 1);
NProgress.status = (n === 1 ? null : n);
var $progress = NProgress.render(!started),
$bar = $progress.find('[role="bar"]'),
speed = Settings.speed,
ease = Settings.easing;
$progress[0].offsetWidth; /* Repaint */
$progress.queue(function(next) {
$bar.css({
transition: 'all '+speed+'ms '+ease,
transform: 'translate3d('+toBarPerc(n)+'%,0,0)'
});
if (n === 1) {
// Fade out
$progress.css({ transition: 'none', opacity: 1 });
$progress[0].offsetWidth; /* Repaint */
setTimeout(function() {
$progress.css({ transition: 'all '+speed+'ms linear', opacity: 0 });
setTimeout(function() {
NProgress.remove();
next();
}, speed);
}, speed);
} else {
setTimeout(next, speed);
}
});
return this;
};
NProgress.isStarted = function() {
return typeof NProgress.status === 'number';
};
/**
* Shows the progress bar.
* This is the same as setting the status to 0%, except that it doesn't go backwards.
*
* NProgress.start();
*
*/
NProgress.start = function() {
if (!NProgress.status) NProgress.set(0);
var work = function() {
setTimeout(function() {
if (!NProgress.status) return;
NProgress.trickle();
work();
}, Settings.trickleSpeed);
};
if (Settings.trickle) work();
return this;
};
/**
* Hides the progress bar.
* This is the *sort of* the same as setting the status to 100%, with the
* difference being `done()` makes some placebo effect of some realistic motion.
*
* NProgress.done();
*
* If `true` is passed, it will show the progress bar even if its hidden.
*
* NProgress.done(true);
*/
NProgress.done = function(force) {
if (!force && !NProgress.status) return this;
return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
};
/**
* Increments by a random amount.
*/
NProgress.inc = function(amount) {
var n = NProgress.status;
if (!n) {
return NProgress.start();
} else {
if (typeof amount !== 'number') {
amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);
}
n = clamp(n + amount, 0, 0.994);
return NProgress.set(n);
}
};
NProgress.trickle = function() {
return NProgress.inc(Math.random() * Settings.trickleRate);
};
/**
* (Internal) renders the progress bar markup based on the `template`
* setting.
*/
NProgress.render = function(fromStart) {
if (NProgress.isRendered()) return $("#nprogress");
$('html').addClass('nprogress-busy');
var $el = $("<div id='nprogress'>")
.html(Settings.template);
var perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0);
$el.find('[role="bar"]').css({
transition: 'all 0 linear',
transform: 'translate3d('+perc+'%,0,0)'
});
$el.appendTo(document.body);
return $el;
};
/**
* (Internal) Removes the element. Opposite of render().
*/
NProgress.remove = function() {
$('html').removeClass('nprogress-busy');
$('#nprogress').remove();
};
/**
* Checks if the progress bar is rendered.
*/
NProgress.isRendered = function() {
return ($("#nprogress").length > 0);
};
/**
* Helpers
*/
function clamp(n, min, max) {
if (n < min) return min;
if (n > max) return max;
return n;
}
/**
* (Internal) converts a percentage (`0..1`) to a bar translateX
* percentage (`-100%..0%`).
*/
function toBarPerc(n) {
return (-1 + n) * 100;
}
return NProgress;
});

View file

@ -4,7 +4,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
<title>{% block title %} {{ title }} {% endblock %}</title>
<meta name="generator" content="frappe">
<link type="text/css" rel="stylesheet" href="{{ docs_base_url }}/assets/css/bootstrap.css">
<link type="text/css" rel="stylesheet" href="{{ docs_base_url }}/assets/css/hljs.css">
@ -12,11 +12,6 @@
<link type="text/css" rel="stylesheet" href="{{ docs_base_url }}/assets/css/octicons/octicons.css">
<link type="text/css" rel="stylesheet" href="{{ docs_base_url }}/assets/css/docs.css">
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/jquery.min.js"></script>
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/bootstrap.min.js"></script>
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/highlight.pack.js"></script>
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/docs.js"></script>
{% block favicon %}
<link rel="shortcut icon"
href="{{ favicon or (docs_base_url + "/assets/img/favicon.png") }}"
@ -37,11 +32,7 @@
{%- block head_include %}{{ head_include or "" }}{% endblock -%}
{%- block style %}
<style>
{%- if style is defined -%}{{ style }}{%- endif -%}
</style>
{%- endblock -%}
{%- block style %}{%- endblock -%}
{%- endblock -%}
</head>
<body data-path="{{ path }}">
@ -60,17 +51,12 @@
{% include "templates/includes/navbar/navbar.html" %}
{%- endblock -%}
<div class="hero-and-content">
{%- block hero -%}
<div data-html-block="hero">
{{ hero or "" }}
</div>
{%- endblock -%}
{% block content %}
<div class="container">
{{ content }}
<!-- edit-link -->
</div>
{% endblock %}
<div data-html-block="hero">
{%- block hero -%}{%- endblock -%}
</div>
<div class="container" data-html-block="content">
{% block content %}{% endblock %}
</div>
</div>
<footer class="docs-footer">
<div class="container">
@ -99,7 +85,7 @@
Forum</a>
</li>
<li>
<a href="https://apps.frappe.io">
<a href="https://frappe.io/apps">
Frappe Apps</a>
</li>
</ul>
@ -120,13 +106,16 @@
</div>
</div>
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/jquery.min.js"></script>
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/bootstrap.min.js"></script>
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/highlight.pack.js"></script>
<script type="text/javascript" src="{{ docs_base_url }}/assets/js/docs.js"></script>
<!-- js should be loaded in body! -->
{%- block script %}
<script>
<script>
window.docs_base_url = "{{ docs_base_url }}";
{%- if script is defined -%}{{ script }}{%- endif -%}
</script>
{%- endblock %}
</script>
{%- block script %}{%- endblock %}
<!-- csrf_token -->
{%- block body_include %}{{ body_include or "" }}{% endblock -%}

View file

@ -4,12 +4,8 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
<title>{% block title %} {{ title }} {% endblock %}</title>
<meta name="generator" content="frappe">
<script type="text/javascript"
src="/assets/frappe/js/lib/jquery/jquery.min.js"></script>
<script type="text/javascript"
src="/assets/js/frappe-web.min.js"></script>
{% block favicon %}
<link rel="shortcut icon"
@ -34,19 +30,19 @@
{%- block head_include %}{{ head_include or "" }}{% endblock -%}
{%- block style %}
<style data-html-block="style">
{%- if style is defined -%}{{ style }}{%- endif -%}
</style>
{%- endblock -%}
{%- block style %}{%- endblock -%}
{%- endblock -%}
{%- if js_globals is defined %}
<script>
{%- for key, value in js_globals.iteritems() %}
window.{{ key }} = "{{ value[0] }}";
{%- endfor -%}
window.frappe = {
page_ready_events: {},
ready: function(fn) {
if (!frappe.page_ready_events[location.pathname]) {
frappe.page_ready_events[location.pathname] = []
}
frappe.page_ready_events[location.pathname].push(fn);
}
}
</script>
{% endif -%}
</head>
<body data-path="{{ path }}">
<div class="offcanvas-container">
@ -64,16 +60,12 @@
{% include "templates/includes/navbar/navbar.html" %}
{%- endblock -%}
<div class="hero-and-content">
{%- block hero -%}
<div data-html-block="hero">
{{ hero or "" }}
</div>
{%- endblock -%}
{% block content %}
<div class="container" data-html-block="content">
{{ content }}
</div>
{% endblock %}
<div data-html-block="hero">
{%- block hero -%}{%- endblock -%}
</div>
<div class="container" data-html-block="content">
{% block content %}{% endblock %}
</div>
</div>
<footer class="page-footer">
<div class="container" data-html-block="footer">
@ -97,21 +89,24 @@
</div>
<!-- js should be loaded in body! -->
<script type="text/javascript"
src="/assets/frappe/js/lib/jquery/jquery.min.js"></script>
<script type="text/javascript"
src="/assets/js/frappe-web.min.js"></script>
{%- if js_globals is defined %}
<script>
{%- for key, value in js_globals.iteritems() %}
window.{{ key }} = "{{ value[0] }}";
{%- endfor -%}
</script>
{% endif -%}
{%- for link in web_include_js %}
<script type="text/javascript" src="{{ link|abs_url }}"></script>
{%- endfor -%}
{%- block script_lib %}
<script data-html-block="script_lib" data-path="{{ name }}">
{%- if script_lib is defined -%}{{ script_lib }}{%- endif -%}
</script>
{%- endblock -%}
{%- block script %}
<script data-html-block="script">
{%- if script is defined -%}{{ script }}{%- endif -%}
</script>
{%- endblock %}
{%- block script %}{%- endblock %}
<!-- csrf_token -->

View file

@ -3,5 +3,7 @@
{% block title %}{{ title }}{% endblock %}
{% block script %}
window.category = "{{ docname }}";
<script>
window.category = "{{ docname }}";
</script>
{% endblock %}

View file

@ -1,10 +1,12 @@
{% extends "templates/web.html" %}
{% block header %}
<h1 itemprop="name headline" itemscope itemtype="http://schema.org/BlogPost">
{{ title }}
</h1>
{% endblock %}
{% block content %}
{% block page_content %}
<article class="blog-content" itemscope itemtype="http://schema.org/BlogPost">
<!-- begin blog content -->
<p class="small text-muted blog-info">
@ -26,19 +28,9 @@
<div class="blog-comments">
<h2>Comments</h2>
{% include 'templates/includes/comments/comments.html' %}
<script>
$(function() {
if(window.logged_in && getCookie("system_user")==="yes") {
frappe.has_permission("Blog Post", "{{ name }}", "write", function(r) {
frappe.require("/assets/frappe/js/frappe/website/editable.js");
frappe.make_editable($('[itemprop="articleBody"]'), "Blog Post", "{{ name }}", "content");
});
}
});
</script>
</div>
<script>
frappe.set_search_path("/blog");
frappe.ready(function() { frappe.set_search_path("/blog"); })
</script>
{% endblock %}

View file

@ -1,3 +1,5 @@
{% extends "templates/web.html" %}
{% block title %}{{ title }}{% endblock %}
{% block header %}
@ -17,7 +19,7 @@
{% endif %}
{% endblock %}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<div class="introduction">
{% if introduction_text %}

View file

@ -1,9 +1,21 @@
{% extends "templates/web.html" %}
{%- block header -%} {{ header or "" }} {%- endblock -%}
{% block content %}
{% block hero %}{{ hero or "" }}{% endblock %}
{% block breadcrumbs %}
{% if not no_breadcrumbs %}
{% include "templates/includes/breadcrumbs.html" %}
{% endif %}
{% endblock %}
{% block page_content %}
<div class="webpage-content">
{% include "templates/includes/slideshow.html" %}
<article class="web-page-content" id="{{ name }}" {% if text_align -%}style="text-align: {{ text_align }}"{%- endif %}>
<article class="web-page-content" id="{{ name }}" {% if text_align -%}styl
e="text-align: {{ text_align }}"{%- endif %}>
{{ main_section or "" }}
</article>
{% if enable_comments -%}
@ -14,6 +26,12 @@
</div>
{% endblock %}
{% block style %}{{ style or "" }}{% endblock %}
{% block style %}
<style>
{{ style or "" }}
</style>
{% endblock %}
{% block script %}{{ script or "" }}{% endblock %}
{% block script %}
<script>{{ script or "" }}</script>
{% endblock %}

View file

@ -1,6 +1,10 @@
{% extends "templates/web.html" %}
{% block title %}{{ blog_title or "Blog" }}{% endblock %}
{% block content %}
{% block hero %}{% endblock %}
{% block page_content %}
<!-- no-header -->
<!-- no-breadcrumbs -->
{% if blog_subtitle %}
@ -17,7 +21,9 @@
</div>
{% endblock %}
{% block script %}{% include "templates/includes/list/list.js" %}{% endblock %}
{% block script %}
<script>{% include "templates/includes/list/list.js" %}</script>
{% endblock %}
{% block style %}
<style>

View file

@ -4,7 +4,7 @@
or (doc.get_route and doc.get_route())
or "{0}/{1}".format(pathname or doc.doctype, doc.name)) %}
<div class="web-list-item">
<a class="no-decoration" href="/{{ route | urlencode }}" no-pjax>
<a class="no-decoration" href="/{{ route | urlencode }}">
<p>{{ subject }}</p>
</a>
</div>

View file

@ -133,13 +133,7 @@ frappe.ready(function() {
login.bind_events();
if (!window.location.hash) {
if (frappe.supports_pjax()) {
// preserve back button
window.history.replaceState(window.history.state, window.document.title, window.location.href + "#login");
$(window).trigger("hashchange");
} else {
window.location.hash = "#login";
}
window.location.hash = "#login";
} else {
$(window).trigger("hashchange");
}

View file

@ -17,4 +17,3 @@
</div>
</nav>
</header>
<script>$(function() { $('.dropdown-toggle').dropdown(); });</script>

View file

@ -15,10 +15,3 @@
{%- endfor %}
{% include "templates/includes/navbar/navbar_login.html" %}
</ul>
{% if include_search %}
<form class="navbar-form navbar-right" role="search">
<div class="form-group">
<input type="text" class="form-control search" placeholder="Search">
</div>
</form>
{% endif %}

View file

@ -1,30 +0,0 @@
<div class="page-container" id="page-{{ name or page_name }}" data-path="{{ pathname }}"
{% if page_or_generator=="Generator" %}data-doctype="{{ doctype }}"{% endif %}>
<div class="page-content">
<div class="page-content-wrapper">
<div class="row">
<div class="col-sm-8">
<div class="page-breadcrumbs" data-html-block="breadcrumbs">
{%- if breadcrumbs is defined -%}{{ breadcrumbs }}{%- endif -%}
</div>
<div class="page-header-block" data-html-block="header">
{%- if header is defined -%}
{% if header %}{{ header }}{% endif %}
{%- endif -%}
</div>
</div>
<div class="col-sm-4">
<div class="page-header-actions-block" data-html-block="header-actions">
{%- if header_actions is defined -%}
{% if header_actions %}{{ header_actions }}{% endif %}
{%- endif -%}
</div>
</div>
</div>
<div class="page-content-block">
{%- block content -%}{{ content or "" }}{%- endblock -%}
</div>
</div>
</div>
</div>

View file

@ -1,23 +0,0 @@
{% if children -%}
<div class="sidebar-items">
{% if parents -%}
<ul class="list-unstyled sidebar-menu sidebar-item">
<li>
<a href="{{ parents[-1].name | abs_url }}" class="no-decoration">
<i class="icon-angle-left"></i> {{ _("Back") }}
</a>
</li>
</ul>
{%- endif %}
{%- for child in children -%}
<ul class="list-unstyled sidebar-menu sidebar-item">
<li>
<a href="{{ child.name | abs_url }}" class="no-decoration
{% if (pathname or "")==(child.name or "") or (pathname and child.name and (pathname.startswith(child.name.lstrip("/")))) -%} active {%- endif %}">
{{ child.title or child.page_title or (child.name or "") }}
</a>
</li>
</ul>
{%- endfor -%}
</div>
{%- endif %}

View file

@ -1,10 +1,12 @@
{% extends "templates/web.html" %}
{%- block title -%}{{_("Not Found")}}{%- endblock -%}
{%- block header -%}
<h1 class="text-danger" style="margin-top: 100px;">{{_("Page missing or moved")}}</h1>
{%- endblock -%}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<div class="404-content" style="margin-bottom: 100px;">
<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>

View file

@ -1,6 +1,8 @@
{% extends "templates/web.html" %}
{% block title %}About Us{% endblock %}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<article class="about-content">
{{ doc.company_introduction or """<p>Some Introduction about your company that you would

View file

@ -1,6 +1,12 @@
{% block style %}{% include "templates/includes/login/login.css" %}{% endblock %}
{% extends "templates/web.html" %}
{% block content %}
{% block style %}
<style>
{% include "templates/includes/login/login.css" %}
</style>
{% endblock %}
{% block page_content %}
<div class="login-content container" style="max-width: 800px;">
<form role="form form-signin" method="POST"
action="/api/method/frappe.templates.pages.login.login_oauth_user">

View file

@ -1,6 +1,8 @@
{% extends "templates/web.html" %}
{% block title %}{{ heading or "Contact Us"}}{% endblock %}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<div class="contact-content">
<div class="row">

View file

@ -1,3 +1,5 @@
{% extends "templates/web.html" %}
{% block title %}Error{% endblock %}
{% block header %}
@ -6,7 +8,7 @@
</h2>
{% endblock %}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<div class="error-content">
<pre><code>{{ error }}</code></pre>

View file

@ -1,3 +1,5 @@
{% extends "templates/web.html" %}
{% block title %}{{ title or (_("{0} List").format(_(doctype))) }}{% endblock %}
{% block header %}
@ -22,6 +24,8 @@
{% endif %}
{% endblock %}
{% block content %}{% include "templates/includes/list/list.html" %}{% endblock %}
{% block page_content %}{% include "templates/includes/list/list.html" %}{% endblock %}
{% block script %}{% include "templates/includes/list/list.js" %}{% endblock %}
{% block script %}
<script>{% include "templates/includes/list/list.js" %}</script>
{% endblock %}

View file

@ -1,6 +1,12 @@
{% block style %}{% include "templates/includes/login/login.css" %}{% endblock %}
{% extends "templates/web.html" %}
{% block content %}
{% block style %}
<style>
{% include "templates/includes/login/login.css" %}
</style>
{% endblock %}
{% block page_content %}
<!-- no-header -->
<!-- no-sidebar -->
<div class="login-content" style="padding-top: 30px; padding-bottom:15px">
@ -71,6 +77,8 @@
</div>
{% endblock %}
{% block script_lib %}{% include "templates/includes/login/login.js" %}{% endblock %}
{% block script %}
<script>{% include "templates/includes/login/login.js" %}</script>
{% endblock %}
{% block sidebar %}{% endblock %}

View file

@ -1,6 +1,8 @@
{% extends "templates/web.html" %}
{% block title %}{{ _("My Account") }}{% endblock %}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<!-- no-cache -->
<div class="row">

View file

@ -1,8 +1,10 @@
{% extends "templates/web.html" %}
{% block title %}{{ title }}{% endblock %}
{% block header %}{{ header }}{% endblock %}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<div class="message-content" style="min-height: 200px;">
<div>

View file

@ -1,6 +1,8 @@
{% extends "templates/web.html" %}
{% block title %} {{_("Reset Password")}} {% endblock %}
{% block content %}
{% block page_content %}
<!-- no-sidebar -->
<div class="row" style="margin-top: 40px; margin-bottom: 20px">
<div class="col-sm-6">
@ -23,7 +25,7 @@
<script>
$(document).ready(function() {
frappe.ready(function() {
if(get_url_arg("key")) {
$("#old_password").parent().toggle(false);
}

31
frappe/templates/web.html Normal file
View file

@ -0,0 +1,31 @@
{% extends base_template_path %}
{% block hero %}{% endblock %}
{% block content %}
<div class="page-container" id="page-{{ name or page_name }}" data-path="{{ pathname }}"
{% if page_or_generator=="Generator" %}data-doctype="{{ doctype }}"{% endif %}>
<div class="page-content">
<div class="page-content-wrapper">
<div class="row">
<div class="col-sm-8">
<div class="page-breadcrumbs" data-html-block="breadcrumbs">
{% block breadcrumbs %}{% endblock %}
</div>
<div class="page-header-block" data-html-block="header">
{% block header %}{% endblock %}
</div>
</div>
<div class="col-sm-4">
<div class="page-header-actions-block" data-html-block="header-actions">
{% block header_actions %}{% endblock %}
</div>
</div>
</div>
<div class="page-content-block">
{%- block page_content -%}{%- endblock -%}
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -96,6 +96,7 @@ def get_jloader():
from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader
apps = frappe.get_installed_apps(sort=True)
apps.reverse()
frappe.local.jloader = ChoiceLoader(

View file

@ -333,8 +333,9 @@ class setup_docs(object):
context.favicon = "/assets/img/favicon.ico"
context.only_static = True
context.base_template_path = "templates/autodoc/base_template.html"
html = frappe.get_template("templates/autodoc/base_template.html").render(context)
html = frappe.get_template("templates/generators/web_page.html").render(context)
if not "<!-- autodoc -->" in html:
html = html.replace('<!-- edit-link -->',

View file

@ -5,41 +5,16 @@ from __future__ import unicode_literals
import frappe
from frappe.website.doctype.website_settings.website_settings import get_website_settings
from frappe.website.template import build_template
from frappe.website.router import get_route_info
from frappe.website.utils import can_cache
def get_context(path, args=None):
context = None
context_cache = {}
context = get_route_info(path)
def add_data_path(context):
if not context.data:
context.data = {}
if args:
context.update(args)
context.data["path"] = path
# try from cache
if can_cache():
context_cache = frappe.cache().hget("page_context", path) or {}
context = context_cache.get(frappe.local.lang, None)
if not context:
context = get_route_info(path)
if args:
context.update(args)
context = build_context(context)
add_data_path(context)
if can_cache(context.no_cache):
context_cache[frappe.local.lang] = context
frappe.cache().hset("page_context", path, context_cache)
else:
add_data_path(context)
context.update(context.data or {})
context = build_context(context)
context["path"] = path
return context
@ -90,9 +65,6 @@ def build_context(context):
app_base = frappe.get_hooks("base_template")
context.base_template_path = app_base[0] if app_base else "templates/base.html"
if context.get("base_template_path") != context.get("template") and not context.get("rendered"):
context.data = build_template(context)
return context
def add_metatags(context):

View file

@ -4,13 +4,15 @@
from __future__ import unicode_literals
import frappe, re, os, json, imp
import requests, requests.exceptions
from frappe.utils import strip_html
from frappe.website.website_generator import WebsiteGenerator
from frappe.website.router import resolve_route
from frappe.website.doctype.website_slideshow.website_slideshow import get_slideshow
from frappe.website.utils import find_first_image, get_comment_list
from frappe.website.utils import find_first_image, get_comment_list, get_full_index
from markdown2 import markdown
from frappe.utils.jinja import render_template
from jinja2.exceptions import TemplateSyntaxError
from frappe import _
class WebPage(WebsiteGenerator):
save_versions = True
@ -74,6 +76,9 @@ class WebPage(WebsiteGenerator):
context["no_header"] = 1
self.set_metatags(context)
self.set_breadcrumbs(context)
self.set_title_and_header(context)
self.add_index(context)
return context
@ -90,8 +95,94 @@ class WebPage(WebsiteGenerator):
if is_jinja:
raise
def get_static_content(self, context):
def set_breadcrumbs(self, context):
"""Build breadcrumbs template (deprecated)"""
if not "no_breadcrumbs" in context:
if "<!-- no-breadcrumbs -->" in context.main_section:
context.no_breadcrumbs = 1
def set_title_and_header(self, context):
"""Extract and set title and header from content or context."""
if not "no_header" in context:
if "<!-- no-header -->" in context.main_section:
context.no_header = 1
if "<!-- title:" in context.main_section:
context.title = re.findall('<!-- title:([^>]*) -->', context.main_section)[0].strip()
if context.get("page_titles") and context.page_titles.get(context.pathname):
context.title = context.page_titles.get(context.pathname)[0]
# header
if "header" in context:
context.header = ""
if not context.no_header:
# if header not set and no h1 tag in the body, set header as title
if not context.header and "<h1" not in context.main_section:
context.header = context.title
# add h1 tag to header
if context.get("header") and not re.findall("<h.>", context.header):
context.header = "<h1>" + context.header + "</h1>"
# if title not set, set title from header
if not context.title and context.header:
context.title = strip_html(context.header)
def add_index(self, 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 context.main_section and context.get("children") and len(context.children):
full_index = get_full_index(context.pathname, extn = extn)
if full_index:
html = frappe.get_template("templates/includes/full_index.html").render({
"full_index": full_index,
"url_prefix": context.url_prefix
})
context.main_section = context.main_section.replace("{index}", html)
# next and previous
if "{next}" in context.main_section:
next_item = self.get_next()
next_item.extn = "" if self.has_children(next_item.name) else extn
if next_item and next_item.page_name:
if context.relative_links:
if next_item.next_parent:
next_item.name = "../" + next_item.page_name or ""
else:
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 not next_item.title:
next_item.title = ""
html = ('<p class="btn-next-wrapper">'+_("Next")\
+': <a class="btn-next" href="{name}{extn}">{title}</a></p>').format(**next_item)
else:
html = ""
context.main_section = context.main_section.replace("{next}", html)
def add_hero(self, context):
"""Add a hero element if specified in content or hooks.
Hero elements get full page width."""
context.hero = ""
if "<!-- start-hero -->" in context.main_section:
parts1 = context.main_section.split("<!-- start-hero -->")
parts2 = parts1[1].split("<!-- end-hero -->")
context.main_section = parts1[0] + parts2[1]
context.hero = parts2[0]
def get_static_content(self, context):
with open(self.template_path, "r") as contentfile:
content = unicode(contentfile.read(), 'utf-8')

View file

@ -197,175 +197,6 @@ $.extend(frappe, {
$(".user-image").attr("src", frappe.get_cookie("user_image"));
}
},
setup_push_state: function() {
if(frappe.supports_pjax()) {
// hack for chrome's onload popstate call
window.initial_href = window.location.href
$(document).on("click", "a", frappe.handle_click);
$(window).on("popstate", function(event) {
// don't run this on hash change
if (location.hash && (!window.previous_href || window.previous_href.replace(location.hash, '') ===
location.href.replace(location.hash, '')))
return;
// hack for chrome's onload popstate call
if(window.initial_href==location.href && window.previous_href==undefined) {
window.history.replaceState({"reload": true},
window.document.title, location.href);
return;
}
window.previous_href = location.href;
var state = event.originalEvent.state;
if(!state) {
window.location.reload();
return;
}
frappe.render_json(state);
});
}
},
handle_click: function(event) {
// taken from jquery pjax
var link = event.currentTarget
if (link.tagName.toUpperCase() !== 'A')
throw "using pjax requires an anchor element";
// Middle click, cmd click, and ctrl click should open
// links in a new tab as normal.
if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
return;
if (link.getAttribute("target"))
return;
// Ignore cross origin links
if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
return;
// Ignore anchors on the same page
if (link.hash && link.href.replace(link.hash, '') ===
location.href.replace(location.hash, ''))
return;
// Ignore empty anchor "foo.html#"
if (link.href === location.href + '#')
return;
// our custom logic
if (link.href.indexOf("cmd=")!==-1 || link.hasAttribute("no-pjax"))
return;
// has an extension, but is not htm/html
var last_part = (link.href.split("/").slice(-1)[0] || "");
if (last_part.indexOf(".")!==-1 && (last_part.indexOf(".htm")===-1))
return;
event.preventDefault();
frappe.load_via_ajax(link.href);
},
load_via_ajax: function(href) {
// console.log("calling ajax", href);
window.previous_href = href;
history.pushState(null, null, href);
var _render = function(data) {
try {
history.replaceState(data, data.title, href);
} catch(e) {
// data too big (?)
history.replaceState(null, data.title, href);
}
scroll(0,0);
frappe.render_json(data);
};
frappe.freeze();
$.ajax({
url: href,
cache: false,
statusCode: {
200: _render,
404: function(xhr) { _render(xhr.responseJSON); }
}
}).fail(function(xhr, status, error) {
window.location.reload();
}).always(function() {
frappe.unfreeze();
});
},
render_json: function(data) {
if (data.reload) {
window.location.reload();
return;
}
$('[data-html-block]').each(function(i, section) {
var $section = $(section);
var stype = $section.attr("data-html-block");
// handle meta separately
if (stype==="meta_block") return;
var block_data = data[stype] || "";
// NOTE: use frappe.ready instead of $.ready for reliable execution
if(stype==="script") {
$section.remove();
$("<script data-html-block='script'></script>")
.html(block_data)
.appendTo("body");
} else if(stype==="script_lib") {
// render once
if(!$("[data-block-html='script_lib'][data-path='"+data.path+"']").length) {
$("<script data-block-html='script_lib' data-path='"+data.path+"'></script>")
.html(data.script_lib)
.appendTo("body");
}
} else {
$section.html(block_data);
}
});
if(data.title) $("title").html(data.title);
// change meta tags
$('[data-html-block="meta_block"]').remove();
if(data.meta_block) {
$("head").append(data.meta_block);
}
// change id of current page
$(".page-container").attr("id", "page-" + data.path);
// set data-path value in body
$("body").attr("data-path", data.path);
// clear page-header-right
$(".page-header-right").html("");
window.ga && ga('send', 'pageview', location.pathname);
$(document).trigger("page-change");
},
supports_pjax: function() {
return (window.history && window.history.pushState && window.history.replaceState &&
// pushState isn't reliable on iOS until 5.
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/))
},
get_pathname: function() {
return location.pathname;
},
page_ready_events: {},
ready: function(fn) {
// console.log("frappe.ready", frappe.get_pathname());
if (!frappe.page_ready_events[frappe.get_pathname()]) {
frappe.page_ready_events[frappe.get_pathname()] = []
}
frappe.page_ready_events[frappe.get_pathname()].push(fn);
},
freeze_count: 0,
freeze: function(msg) {
// blur
@ -395,7 +226,7 @@ $.extend(frappe, {
},
trigger_ready: function() {
var ready_functions = frappe.page_ready_events[frappe.get_pathname()];
var ready_functions = frappe.page_ready_events[location.pathname];
if (ready_functions && ready_functions.length) {
for (var i=0, l=ready_functions.length; i < l; i++) {
var ready = ready_functions[i];
@ -404,7 +235,7 @@ $.extend(frappe, {
}
// remove them so that they aren't fired again and again!
delete frappe.page_ready_events[frappe.get_pathname()];
delete frappe.page_ready_events[location.pathname];
},
highlight_code_blocks: function() {
if(hljs) {
@ -620,24 +451,24 @@ $(document).ready(function() {
// switch to app link
if(getCookie("system_user")==="yes") {
$("#website-post-login .dropdown-menu").append('<li><a href="/desk" no-pjax>Switch To Desk</a></li>');
$("#website-post-login .dropdown-menu").append('<li><a href="/desk">Switch To Desk</a></li>');
}
frappe.render_user();
frappe.setup_push_state();
$(document).trigger("page-change");
});
$(document).on("page-change", function() {
$(document).trigger("apply_permissions");
$('.dropdown-toggle').dropdown();
frappe.datetime.refresh_when();
frappe.toggle_template_blocks();
frappe.trigger_ready();
frappe.bind_filters();
frappe.highlight_code_blocks();
frappe.make_navbar_active();
// scroll to hash
if (window.location.hash) {
var element = document.getElementById(window.location.hash.substring(1));

View file

@ -95,16 +95,10 @@ def render_page(path):
out = None
if can_cache():
if is_ajax():
# ajax, send context
context_cache = frappe.cache().hget("page_context", path)
if context_cache and frappe.local.lang in context_cache:
out = context_cache[frappe.local.lang].get("data")
else:
# return rendered page
page_cache = frappe.cache().hget("website_page", path)
if page_cache and frappe.local.lang in page_cache:
out = page_cache[frappe.local.lang]
# return rendered page
page_cache = frappe.cache().hget("website_page", path)
if page_cache and frappe.local.lang in page_cache:
out = page_cache[frappe.local.lang]
if out:
frappe.local.response.from_cache = True
@ -116,27 +110,24 @@ def build(path):
if not frappe.db:
frappe.connect()
build_method = (build_json if is_ajax() else build_page)
try:
return build_method(path)
return build_page(path)
except frappe.DoesNotExistError:
hooks = frappe.get_hooks()
if hooks.website_catch_all:
path = hooks.website_catch_all[0]
return build_method(path)
return build_page(path)
else:
raise
def build_json(path):
return get_context(path).data
def build_page(path):
if not getattr(frappe.local, "path", None):
frappe.local.path = path
context = get_context(path)
html = frappe.get_template(context.base_template_path).render(context)
html = frappe.get_template(context.template).render(context)
# 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 {}
@ -145,9 +136,6 @@ def build_page(path):
return html
def is_ajax():
return getattr(frappe.local, "is_ajax", False)
def resolve_path(path):
if not path:
path = "index"
@ -238,11 +226,5 @@ def get_doctype_from_path(path):
return None, None
def add_csrf_token(data):
if is_ajax() or frappe.session.user == "Guest" or not frappe.local.session.data.csrf_token:
pass
else:
data = data.replace("<!-- csrf_token -->", '<script>frappe.csrf_token = "{0}";</script>'.format(
return data.replace("<!-- csrf_token -->", '<script>frappe.csrf_token = "{0}";</script>'.format(
frappe.local.session.data.csrf_token))
return data

View file

@ -1,163 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import strip_html
from frappe.website.utils import get_full_index
from frappe import _
from jinja2.utils import concat
from jinja2 import meta
import re
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(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 separate_style_and_script(out, context):
"""Extract `style` and `script` tags into separate blocks"""
out["style"] = re.sub("</?style[^<>]*>", "", out.get("style") or "")
out["script"] = re.sub("</?script[^<>]*>", "", out.get("script") or "")
def set_breadcrumbs(out, context):
"""Build breadcrumbs template (deprecated)"""
out["no_breadcrumbs"] = context.get("no_breadcrumbs", 0) \
or ("<!-- no-breadcrumbs -->" in out.get("content", ""))
if out["no_breadcrumbs"]:
out["breadcrumbs"] = ""
elif "breadcrumbs" not in out:
out["breadcrumbs"] = frappe.get_template("templates/includes/breadcrumbs.html").render(context)
def set_title_and_header(out, context):
"""Extract and set title and header from content or context."""
out["no_header"] = context.get("no_header", 0) or ("<!-- no-header -->" in out.get("content", ""))
if "<!-- title:" in out.get("content", ""):
out["title"] = re.findall('<!-- title:([^>]*) -->', out.get("content"))[0].strip()
if "title" not in out:
out["title"] = context.get("title")
if context.get("page_titles") and context.page_titles.get(context.pathname):
out["title"] = context.page_titles.get(context.pathname)[0]
# header
if out["no_header"]:
out["header"] = ""
else:
if "title" not in out and out.get("header"):
out["title"] = out["header"]
if not out.get("header") and "<h1" not in out.get("content", ""):
if out.get("title"):
out["header"] = out["title"]
if out.get("header") and not re.findall("<h.>", out["header"]):
out["header"] = "<h1>" + out["header"] + "</h1>"
if not out.get("header"):
out["no_header"] = 1
out["title"] = strip_html(out.get("title") or "")
def set_sidebar(out, context):
"""Include sidebar (deprecated)"""
out["has_sidebar"] = not (context.get("no_sidebar", 0) or ("<!-- no-sidebar -->" in out.get("content", "")))
if out.get("has_sidebar"):
out["sidebar"] = frappe.get_template("templates/includes/sidebar.html").render(context)
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") and len(context.children):
full_index = get_full_index(context.pathname, extn = extn)
if full_index:
html = frappe.get_template("templates/includes/full_index.html").render({
"full_index": full_index,
"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 next_item and next_item.page_name:
if context.relative_links:
if next_item.next_parent:
next_item.name = "../" + next_item.page_name or ""
else:
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 not next_item.title:
next_item.title = ""
html = ('<p class="btn-next-wrapper">'+_("Next")\
+': <a class="btn-next" href="{name}{extn}">{title}</a></p>').format(**next_item)
else:
html = ""
out["content"] = out["content"].replace("{next}", html)
def add_hero(out, context):
"""Add a hero element if specified in content or hooks.
Hero elements get full page width."""
out["hero"] = ""
if "<!-- start-hero -->" in out["content"]:
parts1 = out["content"].split("<!-- start-hero -->")
parts2 = parts1[1].split("<!-- end-hero -->")
out["content"] = parts1[0] + parts2[1]
out["hero"] = parts2[0]
elif context.hero and context.hero.get(context.pathname):
out["hero"] = frappe.render_template(context.hero[context.pathname][0], context)

View file

@ -6,7 +6,7 @@ import frappe, re, os
def delete_page_cache(path):
cache = frappe.cache()
groups = ("page_context", "website_page", "sitemap_options")
groups = ("website_page", "sitemap_options")
if path:
for name in groups:
cache.hdel(name, path)