[website] fixes for generating docs

This commit is contained in:
Rushabh Mehta 2016-06-23 18:22:03 +05:30
parent 47005e9e02
commit 349a65402f
45 changed files with 134 additions and 70 deletions

View file

@ -4,6 +4,28 @@ import os
import frappe
from frappe.commands import pass_context
@click.command('write-docs')
@pass_context
@click.argument('app')
@click.option('--target', default=None)
@click.option('--local', default=False, is_flag=True, help='Run app locally')
def write_docs(context, app, target=None, local=False):
"Setup docs in target folder of target app"
from frappe.utils.setup_docs import setup_docs
if not target:
target = os.path.abspath(os.path.join("..", "docs", app))
for site in context.sites:
try:
frappe.init(site=site)
frappe.connect()
make = setup_docs(app)
make.make_docs(target, local)
finally:
frappe.destroy()
@click.command('build-docs')
@pass_context
@click.argument('app')
@ -51,5 +73,6 @@ def _build_docs_once(site, app, docs_version, target, local, only_content_update
frappe.destroy()
commands = [
build_docs
build_docs,
write_docs,
]

View file

@ -22,7 +22,7 @@ ERP for managing small and medium sized businesses.
[Get started with the Tutorial](https://frappe.github.io/frappe/user/)
"""
docs_version = "6.x.x"
docs_version = "7.x.x"
def get_context(context):
context.top_bar_items = [

0
frappe/docs/__init__.py Normal file
View file

View file

View file

View file

View file

View file

View file

View file

@ -14,8 +14,7 @@ To render a template,
From `erpnext/public/js/templates/address_list.js`
<p><button class="btn btn-sm btn-default btn-address">
{% raw %}<p><button class="btn btn-sm btn-default btn-address">
<i class="icon-plus"></i> New Address</button></p>
{% for(var i=0, l=addr_list.length; i<l; i++) { %}
<hr>
@ -34,7 +33,7 @@ From `erpnext/public/js/templates/address_list.js`
{% } %}
{% if(!addr_list.length) { %}
<p class="text-muted">{%= __("No address added yet.") %}</p>
{% } %}
{% } %}{% endraw %}

View file

View file

View file

View file

View file

@ -14,8 +14,7 @@ To render a template,
From `erpnext/public/js/templates/address_list.js`
<p><button class="btn btn-sm btn-default btn-address">
{% raw %}<p><button class="btn btn-sm btn-default btn-address">
<i class="icon-plus"></i> New Address</button></p>
{% for(var i=0, l=addr_list.length; i<l; i++) { %}
<hr>
@ -34,9 +33,7 @@ From `erpnext/public/js/templates/address_list.js`
{% } %}
{% if(!addr_list.length) { %}
<p class="text-muted">{%= __("No address added yet.") %}</p>
{% } %}
{% } %}{% endraw %}
<!-- markdown -->

View file

View file

View file

@ -3,6 +3,18 @@
# metadata
'''
Load metadata (DocType) class
Example:
meta = frappe.get_meta('User')
if meta.has_field('first_name'):
print "DocType" table has field "first_name"
'''
from __future__ import unicode_literals
import frappe, json
from frappe.utils import cstr, cint

View file

@ -33,7 +33,7 @@ def set_field_property(filters, key, value):
frappe.db.commit()
def render_include(content):
'''render {% include "app/path/filename" in js file %}'''
'''render {% raw %}{% include "app/path/filename" %}{% endraw %} in js file'''
content = cstr(content)

View file

@ -246,6 +246,7 @@ body {
line-height: 1.65em;
color: #454e57;
-webkit-font-smoothing: antialiased;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
}
.container {
max-width: 870px;

View file

@ -5,9 +5,15 @@
body {
font-size: 16px;
line-height: 1.65em;
color: #454e57;
color: #454e57;
// position: relative;
-webkit-font-smoothing: antialiased;
-webkit-font-smoothing: antialiased;
font-family: -apple-system, BlinkMacSystemFont,
"Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
"Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
}
.container {

View file

@ -1,9 +1,9 @@
{% if parents and parents|length > 0 %}
{% if parents and parents|length > 0 and (parents[-1].route) %}
<ul class="breadcrumb">
<li>
<span class="icon icon-angle-left"></span>
<a href="{{ url_prefix }}{{ parents[-1].name | abs_url }}">
{{ parents[-1].page_title or parents[-1].title or parents[-1].label or "" }}</a>
<a href="{{ url_prefix }}{{ parents[-1].route | abs_url }}">
{{ parents[-1].title or parents[-1].label or "" }}</a>
</li>
{#
<!-- {% for parent in parents %}

View file

@ -2,7 +2,7 @@
<ol>
{% for item in children_map[route] %}
<li>
<a href="{{ url_prefix }}{{ item.route }}.html">{{ item.title }}</a>
<a href="{{ url_prefix }}{{ item.route }}">{{ item.title }}</a>
{% if children_map[item.route] %}
{{ make_item_list(item.route, children_map) }}
{% endif %}
@ -11,4 +11,4 @@
</ol>
{% endmacro %}
{{ make_item_list(full_index) }}
{{ make_item_list(route, full_index) }}

View file

@ -14,9 +14,11 @@
<div class="page-content-wrapper">
<div class="row page-head">
<div class="col-sm-8">
{% if not no_breadcrumbs and self.breadcrumbs() %}
{% if not no_breadcrumbs and parents %}
<div class="page-breadcrumbs">
{% block breadcrumbs %}{% endblock %}
{% block breadcrumbs %}
{% include 'templates/includes/breadcrumbs.html' %}
{% endblock %}
</div>
{% endif %}
{% block header %}{% endblock %}

View file

@ -118,7 +118,7 @@ def get_jloader():
if not frappe.local.jloader:
from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader
apps = frappe.get_installed_apps(sort=True)
apps = frappe.local.flags.web_pages_apps or frappe.get_installed_apps(sort=True)
apps.reverse()

View file

@ -6,7 +6,7 @@ Call from command line:
"""
import os, json, frappe, shutil
import os, json, frappe, shutil, re
import frappe.website.statics
from frappe.website.context import get_context
from frappe.utils import markdown
@ -17,6 +17,10 @@ class setup_docs(object):
and templates at `templates/autodoc`
"""
self.app = app
frappe.local.flags.web_pages_folders = ['docs',]
frappe.local.flags.web_pages_apps = [self.app,]
self.hooks = frappe.get_hooks(app_name = self.app)
self.app_title = self.hooks.get("app_title")[0]
self.setup_app_context()
@ -268,41 +272,38 @@ class setup_docs(object):
"""render templates and write files to target folder"""
frappe.local.flags.home_page = "index"
from frappe.website.router import get_pages, make_toc
pages = get_pages()
# clear the user, current folder in target
shutil.rmtree(os.path.join(self.target, "user"), ignore_errors=True)
shutil.rmtree(os.path.join(self.target, "current"), ignore_errors=True)
cnt = 0
for page in frappe.db.sql("""select parent_website_route,
page_name from `tabWeb Page` where ifnull(template_path, '')!=''""", as_dict=True):
if page.parent_website_route:
path = page.parent_website_route + "/" + page.page_name
else:
path = page.page_name
for path, context in pages.iteritems():
print "Writing {0}".format(path)
# set this for get_context / website libs
frappe.local.path = path
context = {
context.update({
"page_links_with_extn": True,
"relative_links": True,
"docs_base_url": self.docs_base_url,
"url_prefix": self.docs_base_url,
}
})
context.update(self.app_context)
context = get_context(path, context)
target_path_fragment = context.template_path.split('/docs/', 1)[1]
target_filename = os.path.join(self.target, target_path_fragment)
if context.basename:
target_path_fragment = context.route + '.html'
else:
# index.html
target_path_fragment = context.route + '/index.html'
# rename .md files to .html
if target_filename.rsplit(".", 1)[1]=="md":
target_filename = target_filename[:-3] + ".html"
target_filename = os.path.join(self.target, target_path_fragment.strip('/'))
context.brand_html = context.top_bar_items = context.favicon = None
@ -324,13 +325,23 @@ class setup_docs(object):
context.top_bar_items = [{"label": '<i class="octicon octicon-search"></i>', "url": "#",
"right": 1}] + context.top_bar_items
context.parents = []
parent_route = os.path.dirname(context.route)
if pages[parent_route]:
context.parents = [pages[parent_route]]
if not context.favicon:
context.favicon = "/assets/img/favicon.ico"
context.only_static = True
context.base_template_path = "templates/autodoc/base_template.html"
html = frappe.get_template("templates/generators/web_page.html").render(context)
if '<code>' in context.source:
context.source = re.sub('\<code\>(.*)\</code\>', '<code>{% raw %}\g<1>{% endraw %}</code>', context.source)
html = frappe.render_template(context.source, context)
html = make_toc(context, html)
if not "<!-- autodoc -->" in html:
html = html.replace('<!-- edit-link -->',

View file

@ -8,10 +8,12 @@ from frappe.website.doctype.website_settings.website_settings import get_website
from frappe.website.router import get_page_context
def get_context(path, args=None):
context = get_page_context(path)
if args:
context.update(args)
if args and args.source:
context = args
else:
context = get_page_context(path)
if args:
context.update(args)
context = build_context(context)

View file

@ -55,7 +55,9 @@ def get_page_context_from_template(path):
for app in frappe.get_installed_apps():
app_path = frappe.get_app_path(app)
for start in ('www', 'templates/pages'):
folders = frappe.local.flags.web_pages_folders or ('www', 'templates/pages')
for start in folders:
search_path = os.path.join(app_path, start, path)
options = (search_path, search_path + '.html', search_path + '.md',
search_path + '/index.html', search_path + '/index.md')
@ -111,10 +113,14 @@ def get_pages():
'''Get all pages. Called for docs / sitemap'''
pages = {}
frappe.local.flags.in_get_all_pages = True
for app in frappe.get_installed_apps():
folders = frappe.local.flags.web_pages_folders or ('www', 'templates/pages')
apps = frappe.local.flags.web_pages_apps or frappe.get_installed_apps()
for app in apps:
app_path = frappe.get_app_path(app)
for start in ('templates/pages', 'www'):
for start in folders:
path = os.path.join(app_path, start)
pages.update(get_pages_from_path(path, app, app_path))
frappe.local.flags.in_get_all_pages = False
@ -166,7 +172,7 @@ def get_page_info(path, app, basepath=None, app_path=None, fname=None):
page_info.template = os.path.relpath(os.path.join(basepath, fname), app_path)
if page_info.basename == 'index':
page_info.basename = os.path.dirname(path).strip('.').strip('/')
page_info.basename = ""
page_info.route = page_info.name = page_info.page_name = os.path.join(os.path.relpath(basepath, path),
page_info.basename).strip('/.')
@ -180,16 +186,15 @@ def get_page_info(path, app, basepath=None, app_path=None, fname=None):
page_info.controller = controller
# get the source
page_info.source = get_source(page_info)
setup_source(page_info)
if page_info.only_content:
# extract properties from HTML comments
load_properties(page_info)
return page_info
def get_source(page_info):
def setup_source(page_info):
'''Get the HTML source of the template'''
from markdown2 import markdown
jenv = frappe.get_jenv()
@ -225,46 +230,52 @@ def get_source(page_info):
else:
html = source
page_info.source = html
# show table of contents
setup_index(page_info)
return html
def setup_index(page_info):
'''Build page sequence from index.txt'''
if page_info.basename=='index':
# load index.txt if loading all pages
index_txt_path = os.path.join(page_info.basepath, 'index.txt')
if os.path.exists(index_txt_path):
page_info.index = open(index_txt_path, 'r').read().splitlines()
def make_toc(context, out):
'''Insert full index (table of contents) for {index} tag'''
from frappe.website.utils import get_full_index
if page_info.basename=='index':
if frappe.local.flags.in_get_all_pages:
# load index.txt if loading all pages
index_txt_path = os.path.join(page_info.basepath, 'index.txt')
if os.path.exists(index_txt_path):
page_info.index = open(index_txt_path, 'r').read().splitlines()
if '{index}' in out:
html = frappe.get_template("templates/includes/full_index.html").render({
"full_index": get_full_index(),
"url_prefix": context.url_prefix or "/",
"route": context.route
})
elif '\n{index}' in page_info.source:
html = frappe.get_template("templates/includes/full_index.html").render({
"full_index": get_full_index(),
"url_prefix": None
})
page_info.source.replace('{index}', html)
out = out.replace('{index}', html)
if (not frappe.local.flags.in_get_all_pages) and ('\n{next}' in page_info.source):
if '{next}' in out:
# insert next link
next_item = None
children_map = get_full_index()
parent_route = os.path.dirname(page_info.route)
parent_route = os.path.dirname(context.route)
children = children_map[parent_route]
if parent_route and children:
for i, c in enumerate(children):
if c.route == page_info.route and i < (len(children) - 1):
if c.route == context.route and i < (len(children) - 1):
next_item = children[i+1]
next_item.url_prefix = context.url_prefix or "/"
if next_item:
html = ('<p class="btn-next-wrapper">'+_("Next")\
+': <a class="btn-next" href="{route}.html">{title}</a></p>').format(**next_item)
if next_item.route and next_item.title:
html = ('<p class="btn-next-wrapper">'+_("Next")\
+': <a class="btn-next" href="{url_prefix}{route}">{title}</a></p>').format(**next_item)
page_info.source.replace('{next}', html)
out = out.replace('{next}', html)
return out
def load_properties(page_info):

View file

@ -185,7 +185,7 @@ def abs_url(path):
def get_full_index(route=None, extn = False):
"""Returns full index of the website for www upto the n-th level"""
if not frappe.local.flags.children_map:
from frappe.websites.router import get_pages
from frappe.website.router import get_pages
children_map = {}
pages = get_pages()