* [enhance] global search in website * [fix] create table query * [website] navbar search in header if set * [minor] navbar_search in website settingsversion-14
@@ -3,7 +3,7 @@ | |||
from __future__ import unicode_literals | |||
import re, copy | |||
import re, copy, os | |||
import MySQLdb | |||
import frappe | |||
from frappe import _ | |||
@@ -197,6 +197,9 @@ class DocType(Document): | |||
self.export_doc() | |||
self.make_controller_template() | |||
if self.has_web_view: | |||
self.set_base_class_for_controller() | |||
# update index | |||
if not self.custom: | |||
self.run_module_method("on_doctype_update") | |||
@@ -226,6 +229,26 @@ class DocType(Document): | |||
frappe.enqueue('frappe.utils.global_search.rebuild_for_doctype', | |||
now=now, doctype=self.name) | |||
def set_base_class_for_controller(self): | |||
'''Updates the controller class to subclass from `WebsiteGenertor`, | |||
if it is a subclass of `Document`''' | |||
controller_path = frappe.get_module_path(frappe.scrub(self.module), | |||
'doctype', frappe.scrub(self.name), frappe.scrub(self.name) + '.py') | |||
with open(controller_path, 'r') as f: | |||
code = f.read() | |||
class_string = '\nclass {0}(Document)'.format(self.name.replace(' ', '')) | |||
if '\nfrom frappe.model.document import Document' in code and class_string in code: | |||
code = code.replace('from frappe.model.document import Document', | |||
'from frappe.website.website_generator import WebsiteGenerator') | |||
code = code.replace('class {0}(Document)'.format(self.name.replace(' ', '')), | |||
'class {0}(WebsiteGenerator)'.format(self.name.replace(' ', ''))) | |||
with open(controller_path, 'w') as f: | |||
f.write(code) | |||
def run_module_method(self, method): | |||
from frappe.modules import load_doctype_module | |||
module = load_doctype_module(self.name, self.module) | |||
@@ -297,6 +320,9 @@ class DocType(Document): | |||
make_boilerplate("controller.js", self.as_dict()) | |||
if self.has_web_view: | |||
templates_path = frappe.get_module_path(frappe.scrub(self.module), 'doctype', frappe.scrub(self.name), 'templates') | |||
if not os.path.exists(templates_path): | |||
os.makedirs(templates_path) | |||
make_boilerplate('templates/controller.html', self.as_dict()) | |||
make_boilerplate('templates/controller_row.html', self.as_dict()) | |||
@@ -17,7 +17,7 @@ import re | |||
import frappe.model.meta | |||
from frappe.utils import now, get_datetime, cstr | |||
from frappe import _ | |||
from types import StringType, UnicodeType | |||
from types import StringType, UnicodeType | |||
from frappe.utils.global_search import sync_global_search | |||
class Database: | |||
@@ -799,9 +799,13 @@ class Database: | |||
where creation >= %s""".format(doctype=doctype), | |||
now_datetime() - relativedelta(minutes=minutes))[0][0] | |||
def get_db_table_columns(self, table): | |||
"""Returns list of column names from given table.""" | |||
return [r[0] for r in self.sql("DESC `%s`" % table)] | |||
def get_table_columns(self, doctype): | |||
"""Returns list of column names from given doctype.""" | |||
return [r[0] for r in self.sql("DESC `tab%s`" % doctype)] | |||
return self.get_db_table_columns('tab' + doctype) | |||
def has_column(self, doctype, column): | |||
"""Returns True if column exists in database.""" | |||
@@ -46,7 +46,6 @@ web_include_css = [ | |||
"assets/css/frappe-web.css" | |||
] | |||
website_route_rules = [ | |||
{"from_route": "/blog", "to_route": "Blog Post"}, | |||
{"from_route": "/blog/<category>", "to_route": "Blog Post"}, | |||
{"from_route": "/kb/<category>", "to_route": "Help Article"} | |||
] | |||
@@ -57,9 +56,6 @@ notification_config = "frappe.core.notifications.get_notification_config" | |||
before_tests = "frappe.utils.install.before_tests" | |||
website_generators = ["Web Page", "Blog Post", "Blog Category", "Web Form", | |||
"Help Article"] | |||
email_append_to = ["Event", "ToDo", "Communication"] | |||
calendars = ["Event"] | |||
@@ -10,11 +10,11 @@ import frappe.model.sync | |||
from frappe.utils.fixtures import sync_fixtures | |||
from frappe.sessions import clear_global_cache | |||
from frappe.desk.notifications import clear_notifications | |||
from frappe.website import render | |||
from frappe.website import render, router | |||
from frappe.desk.doctype.desktop_icon.desktop_icon import sync_desktop_icons | |||
from frappe.core.doctype.language.language import sync_languages | |||
from frappe.modules.utils import sync_customizations | |||
import frappe.utils.help | |||
import frappe.utils.help | |||
def migrate(verbose=True, rebuild_website=False): | |||
'''Migrate all apps to the latest version, will: | |||
@@ -41,6 +41,9 @@ def migrate(verbose=True, rebuild_website=False): | |||
# syncs statics | |||
render.clear_cache() | |||
# add static pages to global search | |||
router.sync_global_search() | |||
frappe.db.commit() | |||
if not frappe.conf.get('global_help_setup'): | |||
@@ -336,6 +336,10 @@ class Document(BaseDocument): | |||
for d in self.get_all_children(): | |||
set_new_name(d) | |||
def get_title(self): | |||
'''Get the document title based on title_field or `title` or `name`''' | |||
return self.get(self.meta.get_title_field()) | |||
def set_title_field(self): | |||
"""Set title field based on template""" | |||
def get_values(): | |||
@@ -203,7 +203,15 @@ class Meta(Document): | |||
return [d for d in self.fields if d.get('is_custom_field')] | |||
def get_title_field(self): | |||
return self.title_field or "name" | |||
'''Return the title field of this doctype, | |||
explict via `title_field`, or `title` or `name`''' | |||
title_field = getattr(self, 'title_field', None) | |||
if not title_field and self.has_field('title'): | |||
title_field = 'title' | |||
else: | |||
title_field = 'name' | |||
return title_field | |||
def process(self): | |||
# don't process for special doctypes | |||
@@ -171,3 +171,4 @@ execute:frappe.rename_doc('Country', 'Syrian Arab Republic', 'Syria', ignore_if_ | |||
frappe.patches.v8_0.rename_listsettings_to_usersettings | |||
frappe.patches.v7_2.update_communications | |||
frappe.patches.v8_0.drop_in_dialog | |||
frappe.patches.v8_0.update_published_in_global_search |
@@ -0,0 +1,18 @@ | |||
import frappe | |||
from frappe.utils.global_search import rebuild_for_doctype | |||
def execute(): | |||
from frappe.website.router import get_doctypes_with_web_view | |||
if not 'published' in frappe.db.get_db_table_columns('__global_search'): | |||
frappe.db.sql('''alter table __global_search | |||
add column `title` varchar(140)''') | |||
frappe.db.sql('''alter table __global_search | |||
add column `route` varchar(140)''') | |||
frappe.db.sql('''alter table __global_search | |||
add column `published` int(1) not null default 0''') | |||
for doctype in get_doctypes_with_web_view(): | |||
rebuild_for_doctype(doctype) | |||
@@ -464,6 +464,17 @@ h6 a { | |||
border-right: none; | |||
border-top: none; | |||
} | |||
.navbar-search { | |||
max-width: 400px; | |||
display: inline-block; | |||
margin: 10px; | |||
margin-top: 9px; | |||
padding: 2px 6px; | |||
height: 26px; | |||
} | |||
.dropdown-menu .navbar-search { | |||
max-width: 180px; | |||
} | |||
.social-icons i { | |||
font-size: 120%; | |||
} | |||
@@ -95,6 +95,19 @@ h1, h2, h3, h4, h5, h6 { | |||
border-top: none; | |||
} | |||
.navbar-search { | |||
max-width: 400px; | |||
display: inline-block; | |||
margin: 10px; | |||
margin-top: 9px; | |||
padding: 2px 6px; | |||
height: 26px; | |||
} | |||
.dropdown-menu .navbar-search { | |||
max-width: 180px; | |||
} | |||
.social-icons i { | |||
font-size: 120%; | |||
} | |||
@@ -13,5 +13,6 @@ | |||
{%- endfor %} | |||
{% block navbar_right_extension %}{% endblock %} | |||
<li class="divider"></li> | |||
{% include "templates/includes/navbar/navbar_search.html" %} | |||
{% include "templates/includes/navbar/dropdown_login.html" %} | |||
</ul> |
@@ -16,5 +16,6 @@ | |||
{% if not only_static %} | |||
{% block navbar_right_extension %}{% endblock %} | |||
{% endif %} | |||
{% include "templates/includes/navbar/navbar_search.html" %} | |||
{% include "templates/includes/navbar/navbar_login.html" %} | |||
</ul> |
@@ -0,0 +1,9 @@ | |||
{% if navbar_search %} | |||
<li> | |||
<form action='/search'> | |||
<input name='q' class='form-control navbar-search' type='text' | |||
value='{{ frappe.form_dict.q or ''}}' | |||
{% if not frappe.form_dict.q%}placeholder="{{ _("Search...") }}"{% endif %}> | |||
</form> | |||
</li> | |||
{% endif %} |
@@ -0,0 +1,6 @@ | |||
{% for d in results %} | |||
<div class='search-result-item'> | |||
<h4><a href="{{ d.route }}">{{ d.title }}</a></h4> | |||
<p>{{ d.preview }}</p> | |||
</div> | |||
{% endfor %} |
@@ -52,11 +52,13 @@ def make_boilerplate(dest, app_name): | |||
frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "www")) | |||
frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates", | |||
"pages"), with_init=True) | |||
frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates", | |||
"generators"), with_init=True) | |||
frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates", | |||
"includes")) | |||
frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "config"), with_init=True) | |||
frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "public", | |||
"css")) | |||
frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "public", | |||
"js")) | |||
with open(os.path.join(dest, hooks.app_name, hooks.app_name, "__init__.py"), "w") as f: | |||
f.write(encode(init_template)) | |||
@@ -11,8 +11,11 @@ def setup_global_search_table(): | |||
frappe.db.sql('''create table __global_search( | |||
doctype varchar(100), | |||
name varchar(140), | |||
title varchar(140), | |||
content text, | |||
fulltext(content), | |||
route varchar(140), | |||
published int(1) not null default 0, | |||
unique (doctype, name)) | |||
COLLATE=utf8mb4_unicode_ci | |||
ENGINE=MyISAM | |||
@@ -46,8 +49,13 @@ def update_global_search(doc): | |||
content.append(field.label + ": " + unicode(doc.get(field.fieldname))) | |||
if content: | |||
published = 0 | |||
if hasattr(doc, 'is_website_published') and doc.meta.allow_guest_to_view: | |||
published = 1 if doc.is_website_published() else 0 | |||
frappe.flags.update_global_search.append( | |||
dict(doctype=doc.doctype, name=doc.name, content='|||'.join(content))) | |||
dict(doctype=doc.doctype, name=doc.name, content='|||'.join(content or ''), | |||
published=published, title=doc.get_title(), route=doc.get('route'))) | |||
def sync_global_search(): | |||
'''Add values from `frappe.flags.update_global_search` to __global_search. | |||
@@ -56,9 +64,9 @@ def sync_global_search(): | |||
for value in frappe.flags.update_global_search: | |||
frappe.db.sql(''' | |||
insert into __global_search | |||
(doctype, name, content) | |||
(doctype, name, content, published, title, route) | |||
values | |||
(%(doctype)s, %(name)s, %(content)s) | |||
(%(doctype)s, %(name)s, %(content)s, %(published)s, %(title)s, %(route)s) | |||
on duplicate key update | |||
content = %(content)s''', value) | |||
@@ -69,11 +77,13 @@ def rebuild_for_doctype(doctype): | |||
searchable fields | |||
:param doctype: Doctype ''' | |||
frappe.flags.update_global_search = [] | |||
frappe.db.sql(''' | |||
delete | |||
from __global_search | |||
where | |||
doctype = (%s)''', doctype, as_dict=True) | |||
doctype = %s''', doctype, as_dict=True) | |||
for d in frappe.get_all(doctype): | |||
update_global_search(frappe.get_doc(doctype, d.name)) | |||
@@ -88,7 +98,8 @@ def delete_for_document(doc): | |||
delete | |||
from __global_search | |||
where | |||
name = (%s)''', (doc.name), as_dict=True) | |||
doctype = %s and | |||
name = %s''', (doc.doctype, doc.name), as_dict=True) | |||
@frappe.whitelist() | |||
def search(text, start=0, limit=20): | |||
@@ -109,6 +120,27 @@ def search(text, start=0, limit=20): | |||
limit {start}, {limit}'''.format(start=start, limit=limit), text, as_dict=True) | |||
return results | |||
@frappe.whitelist(allow_guest=True) | |||
def web_search(text, start=0, limit=20): | |||
'''Search for given text in __global_search where published = 1 | |||
:param text: phrase to be searched | |||
:param start: start results at, default 0 | |||
:param limit: number of results to return, default 20 | |||
:return: Array of result objects''' | |||
text = "+" + text + "*" | |||
results = frappe.db.sql(''' | |||
select | |||
doctype, name, content, title, route | |||
from | |||
__global_search | |||
where | |||
published = 1 and | |||
match(content) against (%s IN BOOLEAN MODE) | |||
limit {start}, {limit}'''.format(start=start, limit=limit), | |||
text, as_dict=True) | |||
return results | |||
@frappe.whitelist() | |||
def get_search_doctypes(text): | |||
'''Search for all t | |||
@@ -29,8 +29,6 @@ def get_context(path, args=None): | |||
if hasattr(frappe.local, 'response') and frappe.local.response.get('context'): | |||
context.update(frappe.local.response.context) | |||
# print frappe.as_json(context) | |||
return context | |||
def update_controller_context(context, controller): | |||
@@ -77,15 +75,16 @@ def build_context(context): | |||
if context.doc: | |||
context.update(context.doc.as_dict()) | |||
context.update(context.doc.get_website_properties()) | |||
if not context.template: | |||
context.template = context.doc.meta.get_web_template() | |||
if hasattr(context.doc, "get_context"): | |||
ret = context.doc.get_context(context) | |||
if ret: | |||
context.update(ret) | |||
if not context.template: | |||
context.template = context.doc.meta.get_web_template() | |||
for prop in ("no_cache", "no_sitemap"): | |||
if not prop in context: | |||
context[prop] = getattr(context.doc, prop, False) | |||
@@ -1,5 +1,6 @@ | |||
{ | |||
"allow_copy": 0, | |||
"allow_guest_to_view": 1, | |||
"allow_import": 1, | |||
"allow_rename": 0, | |||
"autoname": "field:category_name", | |||
@@ -22,6 +23,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 1, | |||
"in_standard_filter": 0, | |||
"label": "Category Name", | |||
@@ -49,6 +51,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 1, | |||
"in_standard_filter": 0, | |||
"label": "Title", | |||
@@ -76,6 +79,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 1, | |||
"in_standard_filter": 0, | |||
"label": "Published", | |||
@@ -104,6 +108,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Route", | |||
@@ -122,18 +127,19 @@ | |||
"unique": 1 | |||
} | |||
], | |||
"has_web_view": 1, | |||
"hide_heading": 0, | |||
"hide_toolbar": 0, | |||
"icon": "fa fa-tag", | |||
"idx": 1, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_published_field": "published", | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 0, | |||
"modified": "2016-12-29 14:40:35.127314", | |||
"modified": "2017-03-06 16:29:05.035486", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Blog Category", | |||
@@ -149,7 +155,6 @@ | |||
"export": 0, | |||
"if_owner": 0, | |||
"import": 0, | |||
"is_custom": 0, | |||
"permlevel": 0, | |||
"print": 1, | |||
"read": 1, | |||
@@ -170,7 +175,6 @@ | |||
"export": 0, | |||
"if_owner": 0, | |||
"import": 0, | |||
"is_custom": 0, | |||
"permlevel": 0, | |||
"print": 1, | |||
"read": 1, | |||
@@ -185,6 +189,7 @@ | |||
"quick_entry": 1, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"show_name_in_global_search": 0, | |||
"sort_order": "DESC", | |||
"track_changes": 1, | |||
"track_seen": 0 |
@@ -0,0 +1,4 @@ | |||
<div> | |||
<a href={{ route }}>{{ title }}</a> | |||
</div> | |||
<!-- this is a sample default list template --> |
@@ -1,5 +1,6 @@ | |||
{ | |||
"allow_copy": 0, | |||
"allow_guest_to_view": 1, | |||
"allow_import": 1, | |||
"allow_rename": 0, | |||
"beta": 0, | |||
@@ -276,7 +277,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 1, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_global_search": 1, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Content", | |||
@@ -322,18 +323,19 @@ | |||
"unique": 0 | |||
} | |||
], | |||
"has_web_view": 1, | |||
"hide_heading": 0, | |||
"hide_toolbar": 0, | |||
"icon": "fa fa-quote-left", | |||
"idx": 1, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_published_field": "published", | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 5, | |||
"modified": "2017-02-20 13:33:26.617917", | |||
"modified": "2017-03-06 16:25:33.410910", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Blog Post", | |||
@@ -383,6 +385,7 @@ | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"route": "/blog", | |||
"show_name_in_global_search": 0, | |||
"sort_order": "ASC", | |||
"title_field": "title", | |||
@@ -12,10 +12,7 @@ from frappe.website.utils import find_first_image, get_comment_list | |||
class BlogPost(WebsiteGenerator): | |||
website = frappe._dict( | |||
condition_field = "published", | |||
template = "templates/generators/blog_post.html", | |||
order_by = "published_on desc", | |||
page_title_field = "title" | |||
order_by = "published_on desc" | |||
) | |||
def make_route(self): | |||
@@ -90,7 +87,6 @@ class BlogPost(WebsiteGenerator): | |||
def get_list_context(context=None): | |||
list_context = frappe._dict( | |||
template = "templates/includes/blog/blog.html", | |||
row_template = "templates/includes/blog/blog_row.html", | |||
get_list = get_blog_list, | |||
hide_filters = True, | |||
children = get_children(), | |||
@@ -1,5 +1,6 @@ | |||
{ | |||
"allow_copy": 0, | |||
"allow_guest_to_view": 1, | |||
"allow_import": 1, | |||
"allow_rename": 0, | |||
"beta": 0, | |||
@@ -21,6 +22,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 1, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Title", | |||
@@ -49,6 +51,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 1, | |||
"in_standard_filter": 1, | |||
"label": "Category", | |||
@@ -78,6 +81,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Published", | |||
@@ -106,6 +110,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -134,6 +139,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Author", | |||
@@ -162,6 +168,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Level", | |||
@@ -191,6 +198,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -218,6 +226,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 1, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Content", | |||
@@ -246,6 +255,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Likes", | |||
@@ -274,6 +284,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Route", | |||
@@ -303,6 +314,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Owner", | |||
@@ -322,18 +334,19 @@ | |||
"unique": 0 | |||
} | |||
], | |||
"has_web_view": 1, | |||
"hide_heading": 0, | |||
"hide_toolbar": 0, | |||
"icon": "icon-file-alt", | |||
"idx": 0, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_published_field": "published", | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 0, | |||
"modified": "2016-12-29 14:39:50.018704", | |||
"modified": "2017-03-06 16:27:58.333205", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Help Article", | |||
@@ -350,7 +363,6 @@ | |||
"export": 1, | |||
"if_owner": 0, | |||
"import": 1, | |||
"is_custom": 0, | |||
"permlevel": 0, | |||
"print": 1, | |||
"read": 1, | |||
@@ -371,7 +383,6 @@ | |||
"export": 0, | |||
"if_owner": 0, | |||
"import": 0, | |||
"is_custom": 0, | |||
"permlevel": 0, | |||
"print": 0, | |||
"read": 1, | |||
@@ -392,7 +403,6 @@ | |||
"export": 0, | |||
"if_owner": 0, | |||
"import": 0, | |||
"is_custom": 0, | |||
"permlevel": 0, | |||
"print": 0, | |||
"read": 1, | |||
@@ -407,6 +417,7 @@ | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"show_name_in_global_search": 0, | |||
"sort_field": "modified", | |||
"sort_order": "DESC", | |||
"title_field": "title", | |||
@@ -9,11 +9,6 @@ from frappe.website.utils import get_comment_list | |||
from frappe import _ | |||
class HelpArticle(WebsiteGenerator): | |||
website = frappe._dict( | |||
condition_field = "published", | |||
template = "templates/generators/help_article.html", | |||
) | |||
def validate(self): | |||
self.set_route() | |||
@@ -58,7 +53,6 @@ def get_list_context(context=None): | |||
list_context = frappe._dict( | |||
title = category or _("Knowledge Base"), | |||
row_template = "templates/includes/kb_row.html", | |||
get_level_class = get_level_class, | |||
show_sidebar = True, | |||
sidebar_items = get_sidebar_items(), | |||
@@ -27,7 +27,7 @@ class PortalSettings(Document): | |||
def sync_menu(self): | |||
'''Sync portal menu items''' | |||
dirty = False | |||
for item in frappe.get_hooks('portal_menu_items'): | |||
for item in frappe.get_hooks('standard_portal_menu_items'): | |||
if item.get('role') and not frappe.db.exists("Role", item.get('role')): | |||
frappe.get_doc({"doctype": "Role", "role_name": item.get('role'), "desk_access": 0}).insert() | |||
if self.add_item(item): | |||
@@ -1,5 +1,6 @@ | |||
{ | |||
"allow_copy": 0, | |||
"allow_guest_to_view": 0, | |||
"allow_import": 0, | |||
"allow_rename": 0, | |||
"autoname": "", | |||
@@ -23,6 +24,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Title", | |||
@@ -50,6 +52,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Route", | |||
@@ -78,6 +81,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 1, | |||
"in_standard_filter": 1, | |||
"label": "Select DocType", | |||
@@ -106,6 +110,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Module", | |||
@@ -135,6 +140,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -161,6 +167,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Is Standard", | |||
@@ -189,6 +196,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Published", | |||
@@ -216,6 +224,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Login Required", | |||
@@ -244,6 +253,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Allow Edit", | |||
@@ -272,6 +282,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Allow Multiple", | |||
@@ -300,6 +311,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Allow Delete", | |||
@@ -328,6 +340,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Allow Print", | |||
@@ -357,6 +370,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Print Format", | |||
@@ -387,6 +401,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Allow Comments", | |||
@@ -415,6 +430,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Allow Incomplete Forms", | |||
@@ -443,6 +459,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Fields", | |||
@@ -470,6 +487,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Introduction", | |||
@@ -497,6 +515,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Web Form Fields", | |||
@@ -525,6 +544,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Max Attachment Size (in MB)", | |||
@@ -553,6 +573,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Actions", | |||
@@ -581,6 +602,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Success Message", | |||
@@ -609,6 +631,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Success URL", | |||
@@ -636,6 +659,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Sidebar Settings", | |||
@@ -665,6 +689,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Show Sidebar", | |||
@@ -693,6 +718,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Sidebar Items", | |||
@@ -723,6 +749,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Payments", | |||
@@ -751,6 +778,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Accept Payment", | |||
@@ -780,6 +808,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Payment Gateway", | |||
@@ -811,6 +840,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Button Label", | |||
@@ -840,6 +870,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Button Help", | |||
@@ -868,6 +899,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -896,6 +928,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Amount Based On Field", | |||
@@ -925,6 +958,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Amount Field", | |||
@@ -954,6 +988,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Amount", | |||
@@ -983,6 +1018,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Currency", | |||
@@ -1012,6 +1048,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Advanced", | |||
@@ -1041,6 +1078,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Web Page Link Text", | |||
@@ -1070,6 +1108,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Breadcrumbs", | |||
@@ -1088,18 +1127,19 @@ | |||
"unique": 0 | |||
} | |||
], | |||
"has_web_view": 1, | |||
"hide_heading": 0, | |||
"hide_toolbar": 0, | |||
"icon": "icon-edit", | |||
"idx": 0, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_published_field": "published", | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 0, | |||
"modified": "2016-12-29 14:39:54.941009", | |||
"modified": "2017-03-06 16:29:35.691485", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Web Form", | |||
@@ -1116,7 +1156,6 @@ | |||
"export": 0, | |||
"if_owner": 0, | |||
"import": 0, | |||
"is_custom": 0, | |||
"permlevel": 0, | |||
"print": 0, | |||
"read": 1, | |||
@@ -1131,6 +1170,7 @@ | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"show_name_in_global_search": 0, | |||
"sort_field": "modified", | |||
"sort_order": "DESC", | |||
"title_field": "title", | |||
@@ -16,9 +16,6 @@ from urllib import urlencode | |||
class WebForm(WebsiteGenerator): | |||
website = frappe._dict( | |||
template = "templates/generators/web_form.html", | |||
condition_field = "published", | |||
page_title_field = "title", | |||
no_cache = 1 | |||
) | |||
@@ -1,5 +1,6 @@ | |||
{ | |||
"allow_copy": 0, | |||
"allow_guest_to_view": 1, | |||
"allow_import": 0, | |||
"allow_rename": 0, | |||
"beta": 0, | |||
@@ -51,7 +52,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_global_search": 1, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Title", | |||
@@ -254,7 +255,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_global_search": 1, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Main Section", | |||
@@ -764,18 +765,19 @@ | |||
"unique": 0 | |||
} | |||
], | |||
"has_web_view": 1, | |||
"hide_heading": 0, | |||
"hide_toolbar": 0, | |||
"icon": "fa fa-file-alt", | |||
"idx": 1, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_published_field": "published", | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 20, | |||
"modified": "2017-02-20 13:33:08.460608", | |||
"modified": "2017-03-06 16:26:47.019511", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Web Page", | |||
@@ -13,12 +13,6 @@ from frappe.utils.jinja import render_template | |||
from jinja2.exceptions import TemplateSyntaxError | |||
class WebPage(WebsiteGenerator): | |||
website = frappe._dict( | |||
template = "templates/generators/web_page.html", | |||
condition_field = "published", | |||
page_title_field = "title", | |||
) | |||
def get_feed(self): | |||
return self.title | |||
@@ -1,5 +1,6 @@ | |||
{ | |||
"allow_copy": 0, | |||
"allow_guest_to_view": 0, | |||
"allow_import": 0, | |||
"allow_rename": 0, | |||
"beta": 0, | |||
@@ -21,6 +22,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Landing Page", | |||
@@ -49,6 +51,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 1, | |||
"in_standard_filter": 0, | |||
"label": "Home Page", | |||
@@ -77,6 +80,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -104,6 +108,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 1, | |||
"in_standard_filter": 0, | |||
"label": "Title Prefix", | |||
@@ -131,6 +136,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -159,6 +165,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Website Theme", | |||
@@ -188,6 +195,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Website Theme Image", | |||
@@ -217,6 +225,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Website Theme Image Link", | |||
@@ -245,6 +254,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Brand", | |||
@@ -274,6 +284,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Brand Image", | |||
@@ -303,6 +314,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Brand HTML", | |||
@@ -330,6 +342,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Set Banner from Image", | |||
@@ -358,6 +371,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Top Bar", | |||
@@ -374,6 +388,35 @@ | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"columns": 0, | |||
"fieldname": "navbar_search", | |||
"fieldtype": "Check", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Include Search in Top Bar", | |||
"length": 0, | |||
"no_copy": 0, | |||
"permlevel": 0, | |||
"precision": "", | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"remember_last_selected_value": 0, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
@@ -385,6 +428,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Top Bar Items", | |||
@@ -414,6 +458,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Banner", | |||
@@ -442,6 +487,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Banner HTML", | |||
@@ -469,6 +515,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Footer", | |||
@@ -496,6 +543,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Copyright", | |||
@@ -524,6 +572,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Address", | |||
@@ -551,6 +600,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Footer Items", | |||
@@ -579,6 +629,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Hide Footer Signup", | |||
@@ -607,6 +658,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Integrations", | |||
@@ -635,6 +687,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Google Analytics ID", | |||
@@ -662,6 +715,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -688,6 +742,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "More Information", | |||
@@ -716,6 +771,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "FavIcon", | |||
@@ -745,6 +801,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Subdomain", | |||
@@ -772,6 +829,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"length": 0, | |||
@@ -799,6 +857,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Disable Signup", | |||
@@ -826,6 +885,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "HTML Header & Robots", | |||
@@ -855,6 +915,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "<head> HTML", | |||
@@ -884,6 +945,7 @@ | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_global_search": 0, | |||
"in_list_view": 0, | |||
"in_standard_filter": 0, | |||
"label": "Robots.txt", | |||
@@ -902,18 +964,18 @@ | |||
"unique": 0 | |||
} | |||
], | |||
"has_web_view": 0, | |||
"hide_heading": 0, | |||
"hide_toolbar": 0, | |||
"icon": "fa fa-cog", | |||
"idx": 1, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_submittable": 0, | |||
"issingle": 1, | |||
"istable": 0, | |||
"max_attachments": 10, | |||
"modified": "2016-12-29 14:40:31.225882", | |||
"modified": "2017-03-07 14:45:46.127265", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Website Settings", | |||
@@ -929,7 +991,6 @@ | |||
"export": 0, | |||
"if_owner": 0, | |||
"import": 0, | |||
"is_custom": 0, | |||
"permlevel": 0, | |||
"print": 1, | |||
"read": 1, | |||
@@ -950,7 +1011,6 @@ | |||
"export": 0, | |||
"if_owner": 0, | |||
"import": 0, | |||
"is_custom": 0, | |||
"permlevel": 1, | |||
"print": 0, | |||
"read": 1, | |||
@@ -965,6 +1025,7 @@ | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"show_name_in_global_search": 0, | |||
"sort_order": "ASC", | |||
"track_changes": 1, | |||
"track_seen": 0 |
@@ -326,4 +326,48 @@ def get_doctypes_with_web_view(): | |||
dict(has_web_view=1)) if frappe.local.module_app[frappe.scrub(d.module)] in installed_apps] | |||
return doctypes | |||
return frappe.cache().get_value('doctypes_with_web_view', _get) | |||
return frappe.cache().get_value('doctypes_with_web_view', _get) | |||
def sync_global_search(): | |||
'''Sync page content in global search''' | |||
from frappe.website.render import render_page | |||
from frappe.utils.global_search import sync_global_search | |||
from bs4 import BeautifulSoup | |||
frappe.flags.update_global_search = [] | |||
frappe.session.user = 'Guest' | |||
frappe.local.no_cache = True | |||
frappe.db.sql('delete from __global_search where doctype="Static Web Page"') | |||
for app in frappe.get_installed_apps(frappe_last=True): | |||
app_path = frappe.get_app_path(app) | |||
folders = frappe.local.flags.web_pages_folders or ('www', 'templates/pages') | |||
for start in folders: | |||
for basepath, folders, files in os.walk(os.path.join(app_path, start)): | |||
for f in files: | |||
if f.endswith('.html') or f.endswith('.md'): | |||
path = os.path.join(basepath, f.rsplit('.', 1)[0]) | |||
try: | |||
content = render_page(path) | |||
soup = BeautifulSoup(content, 'html.parser') | |||
text = '' | |||
route = os.path.relpath(path, os.path.join(app_path, start)) | |||
for div in soup.findAll("div", {'class':'page-content'}): | |||
text += div.text | |||
frappe.flags.update_global_search.append( | |||
dict(doctype='Static Web Page', | |||
name=route, | |||
content=text, | |||
published=1, | |||
title=soup.title.string, | |||
route=route)) | |||
except Exception: | |||
pass | |||
sync_global_search() | |||
@@ -0,0 +1,7 @@ | |||
.search-result { | |||
margin-top: 30px; | |||
} | |||
.search-result-item { | |||
padding-bottom: 15px; | |||
} |
@@ -0,0 +1,51 @@ | |||
{% extends "templates/web.html" %} | |||
{% block page_content %} | |||
<h1>{{ title }}</h1> | |||
<div> | |||
<form action='/search'> | |||
<input name='q' class='form-control' type='text' | |||
style='max-width: 400px; display: inline-block; margin-right: 10px;' | |||
value='{{ frappe.form_dict.q or ''}}' | |||
{% if not frappe.form_dict.q%}placeholder="{{ _("Search...") }}"{% endif %}> | |||
<input type='submit' | |||
class='btn btn-sm btn-primary btn-search' value="{{ _("Search") }}"> | |||
</form> | |||
</div> | |||
{% if results %} | |||
<div class='search-result'> | |||
{% include "templates/includes/search_result.html" %} | |||
</div> | |||
{% if has_more %} | |||
<button class='btn btn-default btn-sm btn-more'>{{ _("More") }}</button> | |||
{% endif %} | |||
{% elif frappe.form_dict.q %} | |||
<p class='text-muted'>{{ _("No matching records. Search something new") }} | |||
{% else %} | |||
<p class='text-muted'>{{ _("Type something in the search box to search") }} | |||
{% endif %} | |||
<script> | |||
frappe.ready(function() { | |||
$('.btn-more').on('click', function() { | |||
frappe.call({ | |||
method: 'frappe.www.search.get_search_results', | |||
args: { | |||
text: '{{ frappe.form_dict.q }}', | |||
start: $('.search-result-item').length, | |||
as_html: 1 | |||
}, | |||
callback: function(r) { | |||
$(r.message.results).appendTo('.search-result'); | |||
$('.btn-more').toggleClass('hidden', !!!r.message.has_more); | |||
} | |||
}); | |||
}); | |||
}); | |||
</script> | |||
{% endblock %} |
@@ -0,0 +1,47 @@ | |||
from __future__ import unicode_literals | |||
import frappe | |||
from frappe.utils.global_search import web_search | |||
from html2text import html2text | |||
from frappe import _ | |||
def get_context(context): | |||
context.no_cache = 1 | |||
if frappe.form_dict.q: | |||
context.title = _('Search Results for "{0}"').format(frappe.form_dict.q) | |||
context.update(get_search_results(frappe.form_dict.q)) | |||
else: | |||
context.title = _('Search') | |||
@frappe.whitelist(allow_guest = True) | |||
def get_search_results(text, start=0, as_html=False): | |||
results = web_search(text, start, limit=21) | |||
out = frappe._dict() | |||
if len(results) == 21: | |||
out.has_more = 1 | |||
results = results[:20] | |||
for d in results: | |||
d.content = html2text(d.content) | |||
index = d.content.lower().index(text.lower()) | |||
d.content = d.content[:index] + '<b>' + d.content[index:][:len(text)] + '</b>' + d.content[index + len(text):] | |||
if index < 40: | |||
start = 0 | |||
prefix = '' | |||
else: | |||
start = index - 40 | |||
prefix = '...' | |||
suffix = '' | |||
if (index + len(text) + 47) < len(d.content): | |||
suffix = '...' | |||
d.preview = prefix + d.content[start:start + len(text) + 87] + suffix | |||
out.results = results | |||
if as_html: | |||
out.results = frappe.render_template('templates/includes/search_result.html', out) | |||
return out |