mirror of
https://github.com/mkdocs/mkdocs.git
synced 2026-03-27 09:58:31 +07:00
Use attribute-based access from MkDocsConfig
This commit is contained in:
@@ -48,9 +48,9 @@ def get_context(
|
||||
if page is not None:
|
||||
base_url = utils.get_relative_url('.', page.url)
|
||||
|
||||
extra_javascript = utils.create_media_urls(config['extra_javascript'], page, base_url)
|
||||
extra_javascript = utils.create_media_urls(config.extra_javascript, page, base_url)
|
||||
|
||||
extra_css = utils.create_media_urls(config['extra_css'], page, base_url)
|
||||
extra_css = utils.create_media_urls(config.extra_css, page, base_url)
|
||||
|
||||
if isinstance(files, Files):
|
||||
files = files.documentation_pages()
|
||||
@@ -75,9 +75,7 @@ def _build_template(
|
||||
Return rendered output for given template as a string.
|
||||
"""
|
||||
# Run `pre_template` plugin events.
|
||||
template = config['plugins'].run_event(
|
||||
'pre_template', template, template_name=name, config=config
|
||||
)
|
||||
template = config.plugins.run_event('pre_template', template, template_name=name, config=config)
|
||||
|
||||
if utils.is_error_template(name):
|
||||
# Force absolute URLs in the nav of error pages and account for the
|
||||
@@ -85,21 +83,21 @@ def _build_template(
|
||||
# See https://github.com/mkdocs/mkdocs/issues/77.
|
||||
# However, if site_url is not set, assume the docs root and server root
|
||||
# are the same. See https://github.com/mkdocs/mkdocs/issues/1598.
|
||||
base_url = urlsplit(config['site_url'] or '/').path
|
||||
base_url = urlsplit(config.site_url or '/').path
|
||||
else:
|
||||
base_url = utils.get_relative_url('.', name)
|
||||
|
||||
context = get_context(nav, files, config, base_url=base_url)
|
||||
|
||||
# Run `template_context` plugin events.
|
||||
context = config['plugins'].run_event(
|
||||
context = config.plugins.run_event(
|
||||
'template_context', context, template_name=name, config=config
|
||||
)
|
||||
|
||||
output = template.render(context)
|
||||
|
||||
# Run `post_template` plugin events.
|
||||
output = config['plugins'].run_event('post_template', output, template_name=name, config=config)
|
||||
output = config.plugins.run_event('post_template', output, template_name=name, config=config)
|
||||
|
||||
return output
|
||||
|
||||
@@ -120,7 +118,7 @@ def _build_theme_template(
|
||||
output = _build_template(template_name, template, files, config, nav)
|
||||
|
||||
if output.strip():
|
||||
output_path = os.path.join(config['site_dir'], template_name)
|
||||
output_path = os.path.join(config.site_dir, template_name)
|
||||
utils.write_file(output.encode('utf-8'), output_path)
|
||||
|
||||
if template_name == 'sitemap.xml':
|
||||
@@ -171,19 +169,19 @@ def _populate_page(page: Page, config: MkDocsConfig, files: Files, dirty: bool =
|
||||
return
|
||||
|
||||
# Run the `pre_page` plugin event
|
||||
page = config['plugins'].run_event('pre_page', page, config=config, files=files)
|
||||
page = config.plugins.run_event('pre_page', page, config=config, files=files)
|
||||
|
||||
page.read_source(config)
|
||||
|
||||
# Run `page_markdown` plugin events.
|
||||
page.markdown = config['plugins'].run_event(
|
||||
page.markdown = config.plugins.run_event(
|
||||
'page_markdown', page.markdown, page=page, config=config, files=files
|
||||
)
|
||||
|
||||
page.render(config, files)
|
||||
|
||||
# Run `page_content` plugin events.
|
||||
page.content = config['plugins'].run_event(
|
||||
page.content = config.plugins.run_event(
|
||||
'page_content', page.content, page=page, config=config, files=files
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -225,7 +223,7 @@ def _build_page(
|
||||
template = env.get_template('main.html')
|
||||
|
||||
# Run `page_context` plugin events.
|
||||
context = config['plugins'].run_event(
|
||||
context = config.plugins.run_event(
|
||||
'page_context', context, page=page, config=config, nav=nav
|
||||
)
|
||||
|
||||
@@ -233,7 +231,7 @@ def _build_page(
|
||||
output = template.render(context)
|
||||
|
||||
# Run `post_page` plugin events.
|
||||
output = config['plugins'].run_event('post_page', output, page=page, config=config)
|
||||
output = config.plugins.run_event('post_page', output, page=page, config=config)
|
||||
|
||||
# Write the output file.
|
||||
if output.strip():
|
||||
@@ -262,21 +260,21 @@ def build(config: MkDocsConfig, live_server: bool = False, dirty: bool = False)
|
||||
# Add CountHandler for strict mode
|
||||
warning_counter = utils.CountHandler()
|
||||
warning_counter.setLevel(logging.WARNING)
|
||||
if config['strict']:
|
||||
if config.strict:
|
||||
logging.getLogger('mkdocs').addHandler(warning_counter)
|
||||
|
||||
try:
|
||||
start = time.monotonic()
|
||||
|
||||
# Run `config` plugin events.
|
||||
config = config['plugins'].run_event('config', config)
|
||||
config = config.plugins.run_event('config', config)
|
||||
|
||||
# Run `pre_build` plugin events.
|
||||
config['plugins'].run_event('pre_build', config=config)
|
||||
config.plugins.run_event('pre_build', config=config)
|
||||
|
||||
if not dirty:
|
||||
log.info("Cleaning site directory")
|
||||
utils.clean_directory(config['site_dir'])
|
||||
utils.clean_directory(config.site_dir)
|
||||
else: # pragma: no cover
|
||||
# Warn user about problems that may occur with --dirty option
|
||||
log.warning(
|
||||
@@ -285,23 +283,23 @@ def build(config: MkDocsConfig, live_server: bool = False, dirty: bool = False)
|
||||
)
|
||||
|
||||
if not live_server: # pragma: no cover
|
||||
log.info(f"Building documentation to directory: {config['site_dir']}")
|
||||
if dirty and site_directory_contains_stale_files(config['site_dir']):
|
||||
log.info(f"Building documentation to directory: {config.site_dir}")
|
||||
if dirty and site_directory_contains_stale_files(config.site_dir):
|
||||
log.info("The directory contains stale files. Use --clean to remove them.")
|
||||
|
||||
# First gather all data from all files/pages to ensure all data is consistent across all pages.
|
||||
|
||||
files = get_files(config)
|
||||
env = config['theme'].get_env()
|
||||
env = config.theme.get_env()
|
||||
files.add_files_from_theme(env, config)
|
||||
|
||||
# Run `files` plugin events.
|
||||
files = config['plugins'].run_event('files', files, config=config)
|
||||
files = config.plugins.run_event('files', files, config=config)
|
||||
|
||||
nav = get_navigation(files, config)
|
||||
|
||||
# Run `nav` plugin events.
|
||||
nav = config['plugins'].run_event('nav', nav, config=config, files=files)
|
||||
nav = config.plugins.run_event('nav', nav, config=config, files=files)
|
||||
|
||||
log.debug("Reading markdown pages.")
|
||||
for file in files.documentation_pages():
|
||||
@@ -310,7 +308,7 @@ def build(config: MkDocsConfig, live_server: bool = False, dirty: bool = False)
|
||||
_populate_page(file.page, config, files, dirty)
|
||||
|
||||
# Run `env` plugin events.
|
||||
env = config['plugins'].run_event('env', env, config=config, files=files)
|
||||
env = config.plugins.run_event('env', env, config=config, files=files)
|
||||
|
||||
# Start writing files to site_dir now that all data is gathered. Note that order matters. Files
|
||||
# with lower precedence get written first so that files with higher precedence can overwrite them.
|
||||
@@ -318,10 +316,10 @@ def build(config: MkDocsConfig, live_server: bool = False, dirty: bool = False)
|
||||
log.debug("Copying static assets.")
|
||||
files.copy_static_files(dirty=dirty)
|
||||
|
||||
for template in config['theme'].static_templates:
|
||||
for template in config.theme.static_templates:
|
||||
_build_theme_template(template, env, files, config, nav)
|
||||
|
||||
for template in config['extra_templates']:
|
||||
for template in config.extra_templates:
|
||||
_build_extra_template(template, files, config, nav)
|
||||
|
||||
log.debug("Building markdown pages.")
|
||||
@@ -331,7 +329,7 @@ def build(config: MkDocsConfig, live_server: bool = False, dirty: bool = False)
|
||||
_build_page(file.page, config, doc_files, nav, env, dirty)
|
||||
|
||||
# Run `post_build` plugin events.
|
||||
config['plugins'].run_event('post_build', config=config)
|
||||
config.plugins.run_event('post_build', config=config)
|
||||
|
||||
counts = warning_counter.get_counts()
|
||||
if counts:
|
||||
@@ -342,7 +340,7 @@ def build(config: MkDocsConfig, live_server: bool = False, dirty: bool = False)
|
||||
|
||||
except Exception as e:
|
||||
# Run `build_error` plugin events.
|
||||
config['plugins'].run_event('build_error', error=e)
|
||||
config.plugins.run_event('build_error', error=e)
|
||||
if isinstance(e, BuildError):
|
||||
log.error(str(e))
|
||||
raise Abort('\nAborted with a BuildError!')
|
||||
|
||||
@@ -106,8 +106,8 @@ def gh_deploy(
|
||||
if not _is_cwd_git_repo():
|
||||
log.error('Cannot deploy - this directory does not appear to be a git repository')
|
||||
|
||||
remote_branch = config['remote_branch']
|
||||
remote_name = config['remote_name']
|
||||
remote_branch = config.remote_branch
|
||||
remote_name = config.remote_name
|
||||
|
||||
if not ignore_version:
|
||||
_check_version(remote_branch)
|
||||
@@ -119,13 +119,13 @@ def gh_deploy(
|
||||
|
||||
log.info(
|
||||
"Copying '%s' to '%s' branch and pushing to GitHub.",
|
||||
config['site_dir'],
|
||||
config['remote_branch'],
|
||||
config.site_dir,
|
||||
config.remote_branch,
|
||||
)
|
||||
|
||||
try:
|
||||
ghp_import.ghp_import(
|
||||
config['site_dir'],
|
||||
config.site_dir,
|
||||
mesg=message,
|
||||
remote=remote_name,
|
||||
branch=remote_branch,
|
||||
@@ -139,7 +139,7 @@ def gh_deploy(
|
||||
log.error(f"Failed to deploy to GitHub with error: \n{e.message}")
|
||||
raise Abort('Deployment Aborted!')
|
||||
|
||||
cname_file = os.path.join(config['site_dir'], 'CNAME')
|
||||
cname_file = os.path.join(config.site_dir, 'CNAME')
|
||||
# Does this repository have a CNAME set for GitHub pages?
|
||||
if os.path.isfile(cname_file):
|
||||
# This GitHub pages repository has a CNAME configured.
|
||||
|
||||
@@ -42,7 +42,7 @@ def serve(
|
||||
site_dir = tempfile.mkdtemp(prefix='mkdocs_')
|
||||
|
||||
def mount_path(config: MkDocsConfig):
|
||||
return urlsplit(config['site_url'] or '/').path
|
||||
return urlsplit(config.site_url or '/').path
|
||||
|
||||
get_config = functools.partial(
|
||||
load_config,
|
||||
@@ -64,13 +64,13 @@ def serve(
|
||||
config = get_config()
|
||||
|
||||
# combine CLI watch arguments with config file values
|
||||
if config["watch"] is None:
|
||||
config["watch"] = watch
|
||||
if config.watch is None:
|
||||
config.watch = watch
|
||||
else:
|
||||
config["watch"].extend(watch)
|
||||
config.watch.extend(watch)
|
||||
|
||||
# Override a few config settings after validation
|
||||
config['site_url'] = 'http://{}{}'.format(config['dev_addr'], mount_path(config))
|
||||
config.site_url = f'http://{config.dev_addr}{mount_path(config)}'
|
||||
|
||||
build(config, live_server=live_server, dirty=dirty)
|
||||
|
||||
@@ -81,7 +81,7 @@ def serve(
|
||||
# Perform the initial build
|
||||
builder(config)
|
||||
|
||||
host, port = config['dev_addr']
|
||||
host, port = config.dev_addr
|
||||
server = LiveReloadServer(
|
||||
builder=builder, host=host, port=port, root=site_dir, mount_path=mount_path(config)
|
||||
)
|
||||
@@ -97,17 +97,17 @@ def serve(
|
||||
|
||||
if live_server:
|
||||
# Watch the documentation files, the config file and the theme files.
|
||||
server.watch(config['docs_dir'])
|
||||
server.watch(config['config_file_path'])
|
||||
server.watch(config.docs_dir)
|
||||
server.watch(config.config_file_path)
|
||||
|
||||
if watch_theme:
|
||||
for d in config['theme'].dirs:
|
||||
for d in config.theme.dirs:
|
||||
server.watch(d)
|
||||
|
||||
# Run `serve` plugin events.
|
||||
server = config['plugins'].run_event('serve', server, config=config, builder=builder)
|
||||
server = config.plugins.run_event('serve', server, config=config, builder=builder)
|
||||
|
||||
for item in config['watch']:
|
||||
for item in config.watch:
|
||||
server.watch(item)
|
||||
|
||||
try:
|
||||
|
||||
@@ -61,20 +61,20 @@ class SearchPlugin(BasePlugin[_PluginConfig]):
|
||||
|
||||
def on_config(self, config: MkDocsConfig, **kwargs) -> MkDocsConfig:
|
||||
"Add plugin templates and scripts to config."
|
||||
if 'include_search_page' in config['theme'] and config['theme']['include_search_page']:
|
||||
config['theme'].static_templates.add('search.html')
|
||||
if not ('search_index_only' in config['theme'] and config['theme']['search_index_only']):
|
||||
if 'include_search_page' in config.theme and config.theme['include_search_page']:
|
||||
config.theme.static_templates.add('search.html')
|
||||
if not ('search_index_only' in config.theme and config.theme['search_index_only']):
|
||||
path = os.path.join(base_path, 'templates')
|
||||
config['theme'].dirs.append(path)
|
||||
if 'search/main.js' not in config['extra_javascript']:
|
||||
config['extra_javascript'].append('search/main.js')
|
||||
if self.config['lang'] is None:
|
||||
config.theme.dirs.append(path)
|
||||
if 'search/main.js' not in config.extra_javascript:
|
||||
config.extra_javascript.append('search/main.js')
|
||||
if self.config.lang is None:
|
||||
# lang setting undefined. Set default based on theme locale
|
||||
validate = _PluginConfig.lang.run_validation
|
||||
self.config['lang'] = validate(config['theme']['locale'].language)
|
||||
self.config.lang = validate(config.theme['locale'].language)
|
||||
# The `python` method of `prebuild_index` is pending deprecation as of version 1.2.
|
||||
# TODO: Raise a deprecation warning in a future release (1.3?).
|
||||
if self.config['prebuild_index'] == 'python':
|
||||
if self.config.prebuild_index == 'python':
|
||||
log.info(
|
||||
"The 'python' method of the search plugin's 'prebuild_index' config option "
|
||||
"is pending deprecation and will not be supported in a future release."
|
||||
@@ -91,22 +91,23 @@ class SearchPlugin(BasePlugin[_PluginConfig]):
|
||||
|
||||
def on_post_build(self, config: MkDocsConfig, **kwargs) -> None:
|
||||
"Build search index."
|
||||
output_base_path = os.path.join(config['site_dir'], 'search')
|
||||
output_base_path = os.path.join(config.site_dir, 'search')
|
||||
search_index = self.search_index.generate_search_index()
|
||||
json_output_path = os.path.join(output_base_path, 'search_index.json')
|
||||
utils.write_file(search_index.encode('utf-8'), json_output_path)
|
||||
|
||||
if not ('search_index_only' in config['theme'] and config['theme']['search_index_only']):
|
||||
assert self.config.lang is not None
|
||||
if not ('search_index_only' in config.theme and config.theme['search_index_only']):
|
||||
# Include language support files in output. Copy them directly
|
||||
# so that only the needed files are included.
|
||||
files = []
|
||||
if len(self.config['lang']) > 1 or 'en' not in self.config['lang']:
|
||||
if len(self.config.lang) > 1 or 'en' not in self.config.lang:
|
||||
files.append('lunr.stemmer.support.js')
|
||||
if len(self.config['lang']) > 1:
|
||||
if len(self.config.lang) > 1:
|
||||
files.append('lunr.multi.js')
|
||||
if 'ja' in self.config['lang'] or 'jp' in self.config['lang']:
|
||||
if 'ja' in self.config.lang or 'jp' in self.config.lang:
|
||||
files.append('tinyseg.js')
|
||||
for lang in self.config['lang']:
|
||||
for lang in self.config.lang:
|
||||
if lang != 'en':
|
||||
files.append(f'lunr.{lang}.js')
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ class Files:
|
||||
# Exclude translation files
|
||||
patterns.append("locales/*")
|
||||
patterns.extend(f'*{x}' for x in utils.markdown_extensions)
|
||||
patterns.extend(config['theme'].static_templates)
|
||||
patterns.extend(config.theme.static_templates)
|
||||
for pattern in patterns:
|
||||
if fnmatch.fnmatch(name.lower(), pattern):
|
||||
return False
|
||||
@@ -123,12 +123,10 @@ class Files:
|
||||
# Theme files do not override docs_dir files
|
||||
path = PurePath(path).as_posix()
|
||||
if path not in self.src_uris:
|
||||
for dir in config['theme'].dirs:
|
||||
for dir in config.theme.dirs:
|
||||
# Find the first theme dir which contains path
|
||||
if os.path.isfile(os.path.join(dir, path)):
|
||||
self.append(
|
||||
File(path, dir, config['site_dir'], config['use_directory_urls'])
|
||||
)
|
||||
self.append(File(path, dir, config.site_dir, config.use_directory_urls))
|
||||
break
|
||||
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@ from mkdocs.utils import meta
|
||||
def build_page(title, path, config, md_src=''):
|
||||
"""Helper which returns a Page object."""
|
||||
|
||||
files = Files(
|
||||
[File(path, config['docs_dir'], config['site_dir'], config['use_directory_urls'])]
|
||||
)
|
||||
files = Files([File(path, config.docs_dir, config.site_dir, config.use_directory_urls)])
|
||||
page = Page(title, list(files)[0], config)
|
||||
# Fake page.read_source()
|
||||
page.markdown, page.meta = meta.get_data(md_src)
|
||||
@@ -26,7 +24,7 @@ def build_page(title, path, config, md_src=''):
|
||||
|
||||
class BuildTests(PathAssertionMixin, unittest.TestCase):
|
||||
def _get_env_with_null_translations(self, config):
|
||||
env = config['theme'].get_env()
|
||||
env = config.theme.get_env()
|
||||
env.add_extension('jinja2.ext.i18n')
|
||||
env.install_null_translations()
|
||||
return env
|
||||
|
||||
@@ -25,7 +25,7 @@ class DummyPlugin(plugins.BasePlugin[_DummyPluginConfig]):
|
||||
|
||||
def on_pre_page(self, content, **kwargs):
|
||||
"""modify page content by prepending `foo` config value."""
|
||||
return f'{self.config["foo"]} {content}'
|
||||
return f'{self.config.foo} {content}'
|
||||
|
||||
def on_nav(self, item, **kwargs):
|
||||
"""do nothing (return None) to not modify item."""
|
||||
@@ -33,7 +33,7 @@ class DummyPlugin(plugins.BasePlugin[_DummyPluginConfig]):
|
||||
|
||||
def on_page_read_source(self, **kwargs):
|
||||
"""create new source by prepending `foo` config value to 'source'."""
|
||||
return f'{self.config["foo"]} source'
|
||||
return f'{self.config.foo} source'
|
||||
|
||||
def on_pre_build(self, **kwargs):
|
||||
"""do nothing (return None)."""
|
||||
|
||||
@@ -168,7 +168,7 @@ class SearchPluginTests(unittest.TestCase):
|
||||
self.assertEqual(result['theme'].static_templates, {'404.html', 'sitemap.xml'})
|
||||
self.assertEqual(len(result['theme'].dirs), 3)
|
||||
self.assertEqual(result['extra_javascript'], ['search/main.js'])
|
||||
self.assertEqual(plugin.config['lang'], [result['theme']['locale'].language])
|
||||
self.assertEqual(plugin.config.lang, [result['theme']['locale'].language])
|
||||
|
||||
def test_event_on_config_lang(self):
|
||||
plugin = search.SearchPlugin()
|
||||
@@ -179,7 +179,7 @@ class SearchPluginTests(unittest.TestCase):
|
||||
self.assertEqual(result['theme'].static_templates, {'404.html', 'sitemap.xml'})
|
||||
self.assertEqual(len(result['theme'].dirs), 3)
|
||||
self.assertEqual(result['extra_javascript'], ['search/main.js'])
|
||||
self.assertEqual(plugin.config['lang'], ['es'])
|
||||
self.assertEqual(plugin.config.lang, ['es'])
|
||||
|
||||
def test_event_on_config_theme_locale(self):
|
||||
plugin = search.SearchPlugin()
|
||||
@@ -192,7 +192,7 @@ class SearchPluginTests(unittest.TestCase):
|
||||
self.assertEqual(result['theme'].static_templates, {'404.html', 'sitemap.xml'})
|
||||
self.assertEqual(len(result['theme'].dirs), 3)
|
||||
self.assertEqual(result['extra_javascript'], ['search/main.js'])
|
||||
self.assertEqual(plugin.config['lang'], [result['theme']['locale'].language])
|
||||
self.assertEqual(plugin.config.lang, [result['theme']['locale'].language])
|
||||
|
||||
def test_event_on_config_include_search_page(self):
|
||||
plugin = search.SearchPlugin()
|
||||
@@ -421,9 +421,7 @@ class SearchIndexTests(unittest.TestCase):
|
||||
def test_page(title, filename, config):
|
||||
test_page = Page(
|
||||
title,
|
||||
File(
|
||||
filename, config['docs_dir'], config['site_dir'], config['use_directory_urls']
|
||||
),
|
||||
File(filename, config.docs_dir, config.site_dir, config.use_directory_urls),
|
||||
config,
|
||||
)
|
||||
test_page.content = """
|
||||
@@ -479,7 +477,7 @@ class SearchIndexTests(unittest.TestCase):
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
base_cfg = load_config()
|
||||
base_cfg['plugins']['search'].config['indexing'] = option
|
||||
base_cfg['plugins']['search'].config.indexing = option
|
||||
|
||||
pages = [
|
||||
test_page('Home', 'index.md', base_cfg),
|
||||
|
||||
@@ -389,7 +389,7 @@ class TestFiles(PathAssertionMixin, unittest.TestCase):
|
||||
)
|
||||
def test_add_files_from_theme(self, tdir, ddir):
|
||||
config = load_config(docs_dir=ddir, theme={'name': None, 'custom_dir': tdir})
|
||||
env = config['theme'].get_env()
|
||||
env = config.theme.get_env()
|
||||
files = get_files(config)
|
||||
self.assertEqual(
|
||||
[file.src_path for file in files],
|
||||
|
||||
Reference in New Issue
Block a user