def get_context(nav, files, config, page=None, base_url=''): """ Return the template context for a given page or template. """ 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_css = utils.create_media_urls(config['extra_css'], page, base_url) # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds. # See https://reproducible-builds.org/specs/source-date-epoch/ timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timegm(datetime.utcnow().utctimetuple()))) return { 'nav': nav, 'pages': files.documentation_pages(), 'base_url': base_url, 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcfromtimestamp(timestamp), 'config': config, 'page': page, }
def get_context(nav, config, page=None): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ if nav is None: return {'page', page} extra_javascript = utils.create_media_urls(nav, config['extra_javascript']) extra_css = utils.create_media_urls(nav, config['extra_css']) # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds. # See https://reproducible-builds.org/specs/source-date-epoch/ timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timegm(datetime.utcnow().utctimetuple()))) return { 'nav': nav, # base_url should never end with a slash. 'base_url': nav.url_context.make_relative('/').rstrip('/'), 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcfromtimestamp(timestamp), 'config': config, 'page': page, }
def get_context(nav, config, page=None): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ if nav is None: return {'page', page} extra_javascript = utils.create_media_urls(nav, config['extra_javascript']) extra_css = utils.create_media_urls(nav, config['extra_css']) # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds. # See https://reproducible-builds.org/specs/source-date-epoch/ timestamp = int( os.environ.get('SOURCE_DATE_EPOCH', timegm(datetime.utcnow().utctimetuple()))) return { 'nav': nav, # base_url should never end with a slash. 'base_url': nav.url_context.make_relative('/').rstrip('/'), 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcfromtimestamp(timestamp), 'config': config, 'page': page, }
def get_context(nav, files, config, page=None, base_url=''): """ Return the template context for a given page or template. """ 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_css = utils.create_media_urls(config['extra_css'], page, base_url) if isinstance(files, Files): files = files.documentation_pages() return { 'nav': nav, 'pages': files, 'base_url': base_url, 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'mkdocs_version': mkdocs.__version__, 'build_date_utc': utils.get_build_datetime(), 'config': config, 'page': page, }
def get_global_context(nav, config): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ site_name = config['site_name'] if config['site_favicon']: site_favicon = nav.url_context.make_relative('/' + config['site_favicon']) else: site_favicon = None page_description = config['site_description'] extra_javascript = utils.create_media_urls(nav, config['extra_javascript']) extra_css = utils.create_media_urls(nav, config['extra_css']) # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds. # See https://reproducible-builds.org/specs/source-date-epoch/ timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timegm(datetime.utcnow().utctimetuple()))) return { 'site_name': site_name, 'site_author': config['site_author'], 'favicon': site_favicon, 'page_description': page_description, # Note that there's intentionally repetition here. Rather than simply # provide the config dictionary we instead pass everything explicitly. # # This helps ensure that we can throughly document the context that # gets passed to themes. 'repo_url': config['repo_url'], 'repo_name': config['repo_name'], 'nav': nav, 'base_url': nav.url_context.make_relative('/'), 'homepage_url': nav.homepage.url, 'site_url': config['site_url'], 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'include_nav': config['include_nav'], 'include_next_prev': config['include_next_prev'], 'copyright': config['copyright'], 'google_analytics': config['google_analytics'], 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcfromtimestamp(timestamp), 'config': config }
def get_global_context(nav, config): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ site_name = config['site_name'] if config['site_favicon']: site_favicon = nav.url_context.make_relative('/' + config['site_favicon']) else: site_favicon = None page_description = config['site_description'] extra_javascript = utils.create_media_urls(nav, config['extra_javascript']) extra_css = utils.create_media_urls(nav, config['extra_css']) return { 'site_name': site_name, 'site_author': config['site_author'], 'favicon': site_favicon, 'page_description': page_description, # Note that there's intentionally repetition here. Rather than simply # provide the config dictionary we instead pass everything explicitly. # # This helps ensure that we can throughly document the context that # gets passed to themes. 'repo_url': config['repo_url'], 'repo_name': config['repo_name'], 'repo_branch': config['repo_branch'], 'repo_docs_dir': config['repo_docs_dir'], 'docs_dir': config['docs_dir'], 'nav': nav, 'base_url': nav.url_context.make_relative('/'), 'homepage_url': nav.homepage.url, 'site_url': config['site_url'], 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'include_nav': config['include_nav'], 'include_next_prev': config['include_next_prev'], 'copyright': config['copyright'], 'google_analytics': config['google_analytics'], 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcnow(), 'config': config }
def get_global_context(nav, config): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ site_name = config['site_name'] if config['site_favicon']: site_favicon = nav.url_context.make_relative('/' + config['site_favicon']) else: site_favicon = None page_description = config['site_description'] extra_javascript = utils.create_media_urls(nav, config['extra_javascript']) extra_css = utils.create_media_urls(nav, config['extra_css']) return { 'site_name': site_name, 'site_author': config['site_author'], 'favicon': site_favicon, 'page_description': page_description, # Note that there's intentionally repetition here. Rather than simply # provide the config dictionary we instead pass everything explicitly. # # This helps ensure that we can throughly document the context that # gets passed to themes. 'repo_url': config['repo_url'], 'repo_name': config['repo_name'], 'nav': nav, 'base_url': nav.url_context.make_relative('/'), 'homepage_url': nav.homepage.url, 'site_url': config['site_url'], 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'include_nav': config['include_nav'], 'include_next_prev': config['include_next_prev'], 'copyright': config['copyright'], 'google_analytics': config['google_analytics'], 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcnow(), 'config': config }
def __call__(self, match): url = match.groups()[0] scheme, netloc, path, query, query, fragment = urlparse(url) if scheme or netloc or not path: # Ignore URLs unless they are a relative link to a markdown file. return self.template % url if self.nav and not utils.is_markdown_file(path): path = utils.create_media_urls(self.nav, [path])[0] elif self.nav: # If the site navigation has been provided, then validate # the internal hyperlink, making sure the target actually exists. target_file = self.nav.file_context.make_absolute(path) if target_file not in self.nav.source_files: source_file = self.nav.file_context.current_file msg = 'The page "%s" contained a hyperlink to "%s" which ' 'is not listed in the "pages" configuration.' assert False, msg % (source_file, target_file) path = utils.get_url_path(target_file, self.nav.use_directory_urls) path = self.nav.url_context.make_relative(path) else: path = utils.get_url_path(path).lstrip("/") # Convert the .md hyperlink to a relative hyperlink to the HTML page. url = urlunparse((scheme, netloc, path, query, query, fragment)) return self.template % url
def test_create_media_urls(self): pages = [{ 'Home': 'index.md' }, { 'About': 'about.md' }, { 'Sub': [ { 'Sub Home': 'index.md' }, { 'Sub About': 'about.md' }, ] }] expected_results = { 'https://media.cdn.org/jq.js': 'https://media.cdn.org/jq.js', 'http://media.cdn.org/jquery.js': 'http://media.cdn.org/jquery.js', '//media.cdn.org/jquery.js': '//media.cdn.org/jquery.js', 'media.cdn.org/jquery.js': './media.cdn.org/jquery.js', 'local/file/jquery.js': './local/file/jquery.js', 'image.png': './image.png', } site_navigation = nav.SiteNavigation(pages) for path, expected_result in expected_results.items(): urls = utils.create_media_urls(site_navigation, [path]) self.assertEqual(urls[0], expected_result)
def __call__(self, match): url = match.groups()[0] scheme, netloc, path, query, query, fragment = urlparse(url) if scheme or netloc: # Ignore URLs unless they are a relative link to a markdown file. return self.template % url if self.nav and not utils.is_markdown_file(path): path = utils.create_media_urls(self.nav, [path])[0] elif self.nav: # If the site navigation has been provided, then validate # the internal hyperlink, making sure the target actually exists. target_file = self.nav.file_context.make_absolute(path) if target_file not in self.nav.source_files: source_file = self.nav.file_context.current_file msg = ('The page "%s" contained a hyperlink to "%s" which ' 'is not listed in the "pages" configuration.') assert False, msg % (source_file, target_file) path = utils.get_url_path(target_file, self.nav.use_directory_urls) path = self.nav.url_context.make_relative(path) else: path = utils.get_url_path(path).lstrip('/') # Convert the .md hyperlink to a relative hyperlink to the HTML page. url = urlunparse((scheme, netloc, path, query, query, fragment)) return self.template % url
def test_create_media_urls(self): expected_results = { 'https://media.cdn.org/jq.js': [ 'https://media.cdn.org/jq.js', 'https://media.cdn.org/jq.js', 'https://media.cdn.org/jq.js' ], 'http://media.cdn.org/jquery.js': [ 'http://media.cdn.org/jquery.js', 'http://media.cdn.org/jquery.js', 'http://media.cdn.org/jquery.js' ], '//media.cdn.org/jquery.js': [ '//media.cdn.org/jquery.js', '//media.cdn.org/jquery.js', '//media.cdn.org/jquery.js' ], 'media.cdn.org/jquery.js': [ 'media.cdn.org/jquery.js', 'media.cdn.org/jquery.js', '../media.cdn.org/jquery.js' ], 'local/file/jquery.js': [ 'local/file/jquery.js', 'local/file/jquery.js', '../local/file/jquery.js' ], 'local\\windows\\file\\jquery.js': [ 'local/windows/file/jquery.js', 'local/windows/file/jquery.js', '../local/windows/file/jquery.js' ], 'image.png': [ 'image.png', 'image.png', '../image.png' ], 'style.css?v=20180308c': [ 'style.css?v=20180308c', 'style.css?v=20180308c', '../style.css?v=20180308c' ], '#some_id': [ '#some_id', '#some_id', '#some_id' ] } cfg = load_config(use_directory_urls=False) pages = [ Page('Home', File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg), Page('About', File('about.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg), Page('FooBar', File('foo/bar.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg) ] for i, page in enumerate(pages): urls = utils.create_media_urls(expected_results.keys(), page) self.assertEqual([v[i] for v in expected_results.values()], urls)
def get_global_context(nav, config): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ extra_javascript = utils.create_media_urls(nav, config['extra_javascript']) extra_css = utils.create_media_urls(nav, config['extra_css']) # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds. # See https://reproducible-builds.org/specs/source-date-epoch/ timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timegm(datetime.utcnow().utctimetuple()))) return { 'nav': nav, # base_url should never end with a slash. 'base_url': nav.url_context.make_relative('/').rstrip('/'), 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcfromtimestamp(timestamp), 'config': config, # TODO: remove the rest in 1.0 as they are deprecated 'site_name': config['site_name'], 'site_url': config['site_url'], 'site_author': config['site_author'], 'homepage_url': nav.homepage.url, 'page_description': config['site_description'], 'favicon': config['site_favicon'], 'repo_url': config['repo_url'], 'repo_name': config['repo_name'], 'include_nav': config['include_nav'], 'include_next_prev': config['include_next_prev'], 'copyright': config['copyright'], 'google_analytics': config['google_analytics'] }
def get_global_context(nav, config): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ extra_javascript = utils.create_media_urls(nav, config['extra_javascript']) extra_css = utils.create_media_urls(nav, config['extra_css']) # Support SOURCE_DATE_EPOCH environment variable for "reproducible" builds. # See https://reproducible-builds.org/specs/source-date-epoch/ timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timegm(datetime.utcnow().utctimetuple()))) return { 'nav': nav, 'base_url': nav.url_context.make_relative('/'), 'extra_css': extra_css, 'extra_javascript': extra_javascript, 'mkdocs_version': mkdocs.__version__, 'build_date_utc': datetime.utcfromtimestamp(timestamp), 'config': config, # TODO: remove the rest in 1.0 as they are deprecated 'site_name': config['site_name'], 'site_url': config['site_url'], 'site_author': config['site_author'], 'homepage_url': nav.homepage.url, 'page_description': config['site_description'], 'favicon': config['site_favicon'], 'repo_url': config['repo_url'], 'repo_name': config['repo_name'], 'include_nav': config['include_nav'], 'include_next_prev': config['include_next_prev'], 'copyright': config['copyright'], 'google_analytics': config['google_analytics'] }
def get_global_context(nav, config): """ Given the SiteNavigation and config, generate the context which is relevant to app pages. """ site_name = config["site_name"] if config["site_favicon"]: site_favicon = nav.url_context.make_relative("/" + config["site_favicon"]) else: site_favicon = None page_description = config["site_description"] extra_javascript = utils.create_media_urls(nav=nav, url_list=config["extra_javascript"]) extra_css = utils.create_media_urls(nav=nav, url_list=config["extra_css"]) return { "site_name": site_name, "site_author": config["site_author"], "favicon": site_favicon, "page_description": page_description, # Note that there's intentionally repetition here. Rather than simply # provide the config dictionary we instead pass everything explicitly. # # This helps ensure that we can throughly document the context that # gets passed to themes. "repo_url": config["repo_url"], "repo_name": config["repo_name"], "nav": nav, "base_url": nav.url_context.make_relative("/"), "homepage_url": nav.homepage.url, "extra_css": extra_css, "extra_javascript": extra_javascript, "include_nav": config["include_nav"], "include_next_prev": config["include_next_prev"], "include_search": config["include_search"], "copyright": config["copyright"], "google_analytics": config["google_analytics"], }
def test_create_media_urls(self): pages = [("index.md", "Home"), ("about.md", "About")] expected_results = { "https://media.cdn.org/jquery.js": "https://media.cdn.org/jquery.js", "http://media.cdn.org/jquery.js": "http://media.cdn.org/jquery.js", "//media.cdn.org/jquery.js": "//media.cdn.org/jquery.js", "media.cdn.org/jquery.js": "./media.cdn.org/jquery.js", "local/file/jquery.js": "./local/file/jquery.js", } site_navigation = nav.SiteNavigation(pages) for path, expected_result in expected_results.items(): urls = utils.create_media_urls(site_navigation, [path]) self.assertEqual(urls[0], expected_result)
def test_create_media_urls(self): pages = [ ('index.md', 'Home'), ('about.md', 'About') ] expected_results = { 'https://media.cdn.org/jquery.js': 'https://media.cdn.org/jquery.js', 'http://media.cdn.org/jquery.js': 'http://media.cdn.org/jquery.js', '//media.cdn.org/jquery.js': '//media.cdn.org/jquery.js', 'media.cdn.org/jquery.js': './media.cdn.org/jquery.js', 'local/file/jquery.js': './local/file/jquery.js', } site_navigation = nav.SiteNavigation(pages) for path, expected_result in expected_results.items(): urls = utils.create_media_urls(site_navigation, [path]) self.assertEqual(urls[0], expected_result)
def test_create_media_urls(self): pages = [ {'Home': 'index.md'}, {'About': 'about.md'}, {'Sub': [ {'Sub Home': 'index.md'}, {'Sub About': 'about.md'}, ]} ] expected_results = { 'https://media.cdn.org/jq.js': 'https://media.cdn.org/jq.js', 'http://media.cdn.org/jquery.js': 'http://media.cdn.org/jquery.js', '//media.cdn.org/jquery.js': '//media.cdn.org/jquery.js', 'media.cdn.org/jquery.js': './media.cdn.org/jquery.js', 'local/file/jquery.js': './local/file/jquery.js', 'image.png': './image.png', } site_navigation = nav.SiteNavigation(load_config(pages=pages)) for path, expected_result in expected_results.items(): urls = utils.create_media_urls(site_navigation, [path]) self.assertEqual(urls[0], expected_result)
def get_context(page, content, nav, toc, meta, config): site_name = config['site_name'] if page.is_homepage or page.title is None: page_title = site_name else: page_title = page.title + ' - ' + site_name if page.is_homepage: page_description = config['site_description'] else: page_description = None if config['site_url']: base = config['site_url'] if not base.endswith('/'): base += '/' canonical_url = urljoin(base, page.abs_url.lstrip('/')) else: canonical_url = None if config['site_favicon']: site_favicon = nav.url_context.make_relative('/' + config['site_favicon']) else: site_favicon = None if config['extra_javascript']: config['extra_javascript'] = utils.create_media_urls(nav=nav, url_list=config['extra_javascript']) if config['extra_css']: config['extra_css'] = utils.create_media_urls(nav=nav, url_list=config['extra_css']) return { 'site_name': site_name, 'site_author': config['site_author'], 'favicon': site_favicon, 'page_title': page_title, 'page_description': page_description, 'content': content, 'toc': toc, 'nav': nav, 'meta': meta, 'base_url': nav.url_context.make_relative('/'), 'homepage_url': nav.homepage.url, 'canonical_url': canonical_url, 'current_page': page, 'previous_page': page.previous_page, 'next_page': page.next_page, # Note that there's intentionally repetition here. Rather than simply # provide the config dictionary we instead pass everything explicitly. # # This helps ensure that we can throughly document the context that # gets passed to themes. 'repo_url': config['repo_url'], 'repo_name': config['repo_name'], 'extra_css': config['extra_css'], 'extra_javascript': config['extra_javascript'], 'include_nav': config['include_nav'], 'include_next_prev': config['include_next_prev'], 'include_search': config['include_search'], 'copyright': config['copyright'], 'google-analytics': config['google-analytics'] }