diff --git a/frappe/__init__.py b/frappe/__init__.py index 779518daa4..f14ffed0aa 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -616,7 +616,8 @@ def get_pymodule_path(modulename, *joins): :param modulename: Python module name. :param *joins: Join additional path elements using `os.path.join`.""" - joins = [scrub(part) for part in joins] + if not "public" in joins: + joins = [scrub(part) for part in joins] return os.path.join(os.path.dirname(get_module(scrub(modulename)).__file__), *joins) def get_module_list(app_name): diff --git a/frappe/commands.py b/frappe/commands.py index b4a8bf0814..aea0a158a9 100644 --- a/frappe/commands.py +++ b/frappe/commands.py @@ -350,11 +350,11 @@ def build_website(context): finally: frappe.destroy() -@click.command('build-dev-docs') +@click.command('make-docs') @pass_context @click.argument('app') @click.argument('docs_version') -def make_dev_docs(context, app, docs_version): +def make_docs(context, app, docs_version): "Setup docs in target folder of target app" from frappe.utils.setup_docs import setup_docs for site in context.sites: @@ -366,24 +366,60 @@ def make_dev_docs(context, app, docs_version): finally: frappe.destroy() -@click.command('make-docs') +@click.command('sync-docs') +@pass_context +@click.argument('app') +def sync_docs(context, app): + "Sync docs from /docs folder into the database (Web Page)" + from frappe.utils.setup_docs import setup_docs + for site in context.sites: + try: + frappe.init(site=site) + frappe.connect() + make = setup_docs(app) + make.sync_docs() + finally: + frappe.destroy() + + +@click.command('write-docs') @pass_context @click.argument('app') @click.argument('target') -def setup_docs(context, app, target): +@click.option('--local', default=False, is_flag=True, help='Run app locally') +def write_docs(context, app, target, local=False): "Setup docs in target folder of target app" from frappe.utils.setup_docs import setup_docs - from frappe.website import statics for site in context.sites: try: frappe.init(site=site) frappe.connect() make = setup_docs(app) - make.make_docs(target) - statics.sync_statics(rebuild=True) + make.make_docs(target, local) finally: frappe.destroy() +@click.command('build-docs') +@pass_context +@click.argument('app') +@click.argument('docs_version') +@click.argument('target') +@click.option('--local', default=False, is_flag=True, help='Run app locally') +def build_docs(context, app, docs_version, target, local=False): + "Setup docs in target folder of target app" + from frappe.utils.setup_docs import setup_docs + for site in context.sites: + try: + frappe.init(site=site) + frappe.connect() + make = setup_docs(app) + make.build(docs_version) + make.sync_docs() + make.make_docs(target, local) + finally: + frappe.destroy() + + @click.command('reset-perms') @pass_context def reset_perms(context): @@ -945,8 +981,10 @@ commands = [ destroy_all_sessions, sync_www, build_website, - make_dev_docs, - setup_docs, + make_docs, + sync_docs, + write_docs, + build_docs, reset_perms, execute, celery, diff --git a/frappe/hooks.py b/frappe/hooks.py index 207fa0505c..3dbd6b96f9 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -29,7 +29,7 @@ to ERPNext. app_icon = "octicon octicon-circuit-board" app_version = "6.6.1" app_color = "orange" -github_link = "https://github.com/frappe/frappe" +source_link = "https://github.com/frappe/frappe" app_email = "info@frappe.io" diff --git a/frappe/public/css/docs.css b/frappe/public/css/docs.css new file mode 100644 index 0000000000..3fdeaa0ecd --- /dev/null +++ b/frappe/public/css/docs.css @@ -0,0 +1,156 @@ +html { + min-height: 100%; +} +body { + height: 100%; + /* The html and body elements cannot have any padding or margin. */ + margin: 0px; + padding: 0px !important; +} +html, +body { + overflow-x: hidden; + /* Prevent scroll on narrow devices */ +} +.offcanvas-main-section-overlay { + display: none; + cursor: pointer; + opacity: 0.5; +} +.sidebar-padding { + padding: 12px 14px; +} +.offcanvas .sidebar .sidebar-menu > li > a, +.offcanvas .sidebar .dropdown-menu > li > a { + padding: 12px 14px; + display: block; + whitespace: nowrap; + transition: 0.2s; + text-decoration: none !important; +} +.offcanvas .sidebar .dropdown-menu { + padding: 0px; + font-size: inherit; +} +.offcanvas .sidebar .dropdown-menu > li > a { + padding-left: 28px; +} +.offcanvas .sidebar .divider { + height: 1px; + overflow: hidden; + background-color: #ebeff2; + width: 100%; + margin: 0px; +} +.offcanvas .sidebar .badge { + right: 15px !important; + top: 11px !important; +} +.offcanvas .sidebar .sidebar-menu > li > a:hover, +.offcanvas .sidebar .dropdown-menu > li > a:hover, +.offcanvas .sidebar .sidebar-menu > li > a:focus, +.offcanvas .sidebar .dropdown-menu > li > a:focus, +.offcanvas .sidebar .sidebar-menu > li > a:active, +.offcanvas .sidebar .dropdown-menu > li > a:active { + background-color: #f0f4f7; +} +.breadcrumb { + line-height: 1.5em; +} +.breadcrumb { + background-color: transparent; + padding: 10px 0px; +} +.breadcrumb a, +.breadcrumb a:hover, +.breadcrumb a:focus, +.breadcrumb a:visited { + color: inherit; +} +.navbar { + background-color: transparent; + border: none; + padding: 10px 0px; + border-radius: 0px; + border-bottom: 1px solid #7575ff; +} +.section { + padding: 30px 0px; +} +.docs-footer { + margin-top: 50px; + padding: 30px 0px 60px 0px; + border-top: 1px solid #d1d8dd; +} +.docs-footer a { + color: #8d99a6; +} +.docs-footer li { + display: inline-block; + margin: 0 15px; +} +.jumbotron { + background-color: transparent; + padding: 80px 30px; + text-align: center; +} +.jumbotron h1 { + font-size: 32px; + font-weight: 400; +} +.jumbotron p { + font-color: #8d99a6 !important; +} +.browser-image { + min-height: 300px; + border: 1px solid #d1d8dd; +} +.fake-browser-frame { + position: relative; + margin: 40px auto; + max-width: 600px; +} +.fake-browser-frame::before { + content: ""; + height: 24px; + position: absolute; + top: -24px; + left: 0px; + right: 0px; + border: 1px solid #d1d8dd; + border-bottom: none; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.fake-browser-frame::after { + content: '\f111 \f111 \f111'; + position: absolute; + color: #d1d8dd; + top: -15px; + left: 8px; + /* octicon */ + font: normal normal; + font-size: 8px; + font-family: 'FontAwesome'; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.fake-iphone-frame { + position: relative; + padding: 40px 8px; + border: 1px solid #d1d8dd; + border-radius: 15px; +} +.fake-ipad-frame { + position: relative; + padding: 8px 40px; + border: 1px solid #d1d8dd; + border-radius: 15px; +} diff --git a/frappe/public/images/frappe-bird-grey.svg b/frappe/public/images/frappe-bird-grey.svg new file mode 100644 index 0000000000..de72dc1c51 --- /dev/null +++ b/frappe/public/images/frappe-bird-grey.svg @@ -0,0 +1,13 @@ + + + diff --git a/frappe/public/less/docs.less b/frappe/public/less/docs.less new file mode 100644 index 0000000000..77e7e64604 --- /dev/null +++ b/frappe/public/less/docs.less @@ -0,0 +1,122 @@ +@import "variables.less"; +@import "offcanvas.less"; + +.breadcrumb { + line-height: 1.5em; +} +.breadcrumb { + background-color: transparent; + padding: 10px 0px; +} +.breadcrumb a, +.breadcrumb a:hover, +.breadcrumb a:focus, +.breadcrumb a:visited { + color: inherit; +} + +.navbar { + background-color: transparent; + border: none; + padding: 10px 0px; + border-radius: 0px; + border-bottom: 1px solid @erpnext-blue; + +} + +.section { + padding: 30px 0px; +} + +.docs-footer { + margin-top: 50px; + padding: 30px 0px 60px 0px; + border-top: 1px solid @border-color; + + a { + color: @text-muted; + } + + li { + display: inline-block; + margin: 0 15px; + } +} + +.jumbotron { + background-color: transparent; + padding: 80px 30px; + text-align: center; + + h1 { + font-size: 32px; + font-weight: 400; + } + + p { + font-color: @text-muted !important; + } +} + +// fake frames +.browser-image { + min-height: 300px; + border: 1px solid #d1d8dd; +} + +.fake-browser-frame { + position: relative; + margin: 40px auto; + max-width: 600px; +} + +.fake-browser-frame::before { + content: ""; + height: 24px; + position: absolute; + top: -24px; + left: 0px; + right: 0px; + border: 1px solid #d1d8dd; + border-bottom: none; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +.fake-browser-frame::after { + content: '\f111 \f111 \f111'; + position: absolute; + color: #d1d8dd; + top: -15px; + left: 8px; + + + /* octicon */ + font: normal normal; + font-size: 8px; + font-family: 'FontAwesome'; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + +.fake-iphone-frame { + position: relative; + padding: 40px 8px; + border: 1px solid #d1d8dd; + border-radius: 15px; +} + +.fake-ipad-frame { + position: relative; + padding: 8px 40px; + border: 1px solid #d1d8dd; + border-radius: 15px; +} diff --git a/frappe/public/less/variables.less b/frappe/public/less/variables.less index d395232890..ac664708ee 100644 --- a/frappe/public/less/variables.less +++ b/frappe/public/less/variables.less @@ -1,4 +1,5 @@ @brand-primary: #5E64FF; +@erpnext-blue: #7575ff; @border-color: #d1d8dd; @light-border-color: #EBEFF2; @text-color: #36414C; diff --git a/frappe/templates/autodoc/api_home.html b/frappe/templates/autodoc/api_home.html index afef9c43e5..7cac4a44ff 100644 --- a/frappe/templates/autodoc/api_home.html +++ b/frappe/templates/autodoc/api_home.html @@ -1,9 +1,9 @@ -{% from "templates/autodoc/macros.html" import github_link, version %} +{% from "templates/autodoc/macros.html" import source_link, version %}
{{ version(app.name) }} -{{ github_link(app, app.name, True) }} +{{ source_link(app, app.name, True) }}