9f0a216c5e
- Created index.html template for the homepage with service cards and partner logos. - Added page_from_md.html template for rendering pages from markdown. - Developed services.html template detailing various services offered. - Implemented tests for link handling in markdown, ensuring external links open in new tabs and internal links function correctly. - Enhanced markdown parser tests to validate heading extraction, content rendering, and link safety. - Introduced utility tests for template rendering, HTML minification, and JavaScript minification. Co-authored-by: Copilot <copilot@github.com>
190 lines
6.4 KiB
Python
190 lines
6.4 KiB
Python
import json
|
|
import os
|
|
from typing import Any, Dict
|
|
from lib.markdown_parser import (
|
|
parse_markdown_file,
|
|
get_markdown_files,
|
|
markdown_filename_to_html_filename,
|
|
)
|
|
from lib.utils import (
|
|
get_template_files,
|
|
render_template,
|
|
set_active_page_by_url,
|
|
minify_html,
|
|
js_minifier,
|
|
)
|
|
from lib.types import PagesDict
|
|
|
|
TEMPLATE_DIR = 'templates'
|
|
OUTPUT_DIR = 'html'
|
|
|
|
PAGES_JSON = 'docs/pages.json'
|
|
|
|
# Load json data for navigation and pages if needed
|
|
with open(PAGES_JSON, 'r') as f:
|
|
PAGES = json.load(f)
|
|
|
|
|
|
# Ensure output directory exists
|
|
if not os.path.exists(OUTPUT_DIR):
|
|
os.makedirs(OUTPUT_DIR)
|
|
|
|
|
|
def get_pages() -> PagesDict:
|
|
"""Load and return pages data from the pages.json file.
|
|
|
|
Returns:
|
|
dict: Pages dictionary structured as follows:
|
|
{
|
|
"page.html": {
|
|
"name": str,
|
|
"url": str,
|
|
"active": str,
|
|
"page_title": str,
|
|
"page_subtitle": str,
|
|
"page_cta": str,
|
|
"page_cta_url": str,
|
|
"meta": {
|
|
"title": str,
|
|
"description": str,
|
|
"keywords": str,
|
|
"og_description": str,
|
|
}
|
|
},
|
|
{...}
|
|
}
|
|
"""
|
|
# Set a default favicon for all pages
|
|
favicon = 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png'
|
|
with open(PAGES_JSON, 'r', encoding='utf-8') as f:
|
|
pages = json.load(f)
|
|
|
|
# Update the meta information for each page
|
|
for page in pages.values():
|
|
page['meta']['favicon'] = favicon
|
|
page['meta']['og_image'] = favicon
|
|
page['meta']['twitter_image'] = favicon
|
|
return pages
|
|
|
|
|
|
def process_markdown_file(
|
|
md_file_path: str,
|
|
output_html_path: str,
|
|
pages: PagesDict,
|
|
template_dir: str = TEMPLATE_DIR,
|
|
):
|
|
"""
|
|
Process a single Markdown file and render it using the page_from_md template.
|
|
|
|
Args:
|
|
md_file_path (str): Full path to the Markdown file.
|
|
output_html_path (str): Full path to write the output HTML.
|
|
pages (dict): Pages dictionary for context.
|
|
"""
|
|
try:
|
|
# Parse the Markdown file
|
|
page_data = parse_markdown_file(md_file_path)
|
|
|
|
# Get the HTML filename to determine active nav
|
|
html_filename = os.path.basename(output_html_path)
|
|
set_active_page_by_url(pages, html_filename)
|
|
|
|
# Build default meta data for the page
|
|
default_meta: Dict[str, Any] = {
|
|
'title': page_data.get('title', ''),
|
|
'description': 'Explore our comprehensive services and coaching programs.',
|
|
'keywords': 'consulting, coaching, services',
|
|
'og_description': page_data.get('title', ''),
|
|
'favicon': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
|
|
'twitter_image': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
|
|
'og_image': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
|
|
}
|
|
page = pages.get(html_filename, {})
|
|
meta = page.get('meta', default_meta)
|
|
page_title = page.get('page_title', page_data.get('title', ''))
|
|
page_subtitle = page.get('page_subtitle', '')
|
|
|
|
# Build context for rendering
|
|
context: Dict[str, Any] = {
|
|
'nav_pages': pages,
|
|
'page': page_data,
|
|
'page_title': page_title,
|
|
'page_subtitle': page_subtitle,
|
|
'meta': meta,
|
|
'page_url': html_filename,
|
|
'page_cta': page.get('page_cta', 'Get Started'),
|
|
'page_cta_url': page.get('page_cta_url', '#contact-form'),
|
|
}
|
|
|
|
# Render the template and write the output
|
|
output = render_template(
|
|
'page_from_md.html', context, template_dir=template_dir)
|
|
html = minify_html(output)
|
|
os.makedirs(os.path.dirname(output_html_path), exist_ok=True)
|
|
with open(output_html_path, 'w', encoding='utf-8') as f:
|
|
f.write(html)
|
|
|
|
print(f'Processed Markdown: {md_file_path} -> {output_html_path}')
|
|
except Exception as e:
|
|
print(f'Error processing Markdown file {md_file_path}: {e}')
|
|
|
|
|
|
def main():
|
|
"""Main function to render templates with navigation context."""
|
|
# Get all pages with their details
|
|
pages = get_pages()
|
|
if not pages:
|
|
print("No pages found to render.")
|
|
return
|
|
# Get navigation pages
|
|
templates = get_template_files(TEMPLATE_DIR)
|
|
if not templates:
|
|
print("No templates found to render.")
|
|
return
|
|
print(f'Found {len(templates)} templates to process.')
|
|
|
|
# # Process each template
|
|
# for template_name in templates:
|
|
# # Skip templates that are not in the pages dictionary
|
|
# if template_name not in pages:
|
|
# print(f'Skipping template: {template_name}')
|
|
# continue
|
|
# print(f'Processing template: {template_name}')
|
|
# # Set the active page based on the template name
|
|
# set_active_page_by_url(pages, template_name)
|
|
# page_details: PageEntry = pages[template_name]
|
|
# context = {
|
|
# 'nav_pages': pages,
|
|
# 'page_title': page_details.get('page_title', ''),
|
|
# 'page_subtitle': page_details.get('page_subtitle', ''),
|
|
# 'page_cta': page_details.get('page_cta', ''),
|
|
# 'page_cta_url': page_details.get('page_cta_url', ''),
|
|
# 'meta': page_details.get('meta', {}),
|
|
# }
|
|
|
|
# output = render_template(
|
|
# template_name, context, template_dir=TEMPLATE_DIR)
|
|
# html = minify_html(output)
|
|
# with open(f'{OUTPUT_DIR}/{template_name}', 'w', encoding='utf-8') as f:
|
|
# f.write(html)
|
|
|
|
# Process Markdown files from docs/en/
|
|
print("\nProcessing Markdown files...")
|
|
markdown_files = get_markdown_files()
|
|
for md_file in markdown_files:
|
|
md_path = os.path.join('docs/en', md_file)
|
|
html_filename = markdown_filename_to_html_filename(md_file)
|
|
html_path = os.path.join(OUTPUT_DIR, html_filename)
|
|
process_markdown_file(md_path, html_path, pages,
|
|
template_dir=TEMPLATE_DIR)
|
|
|
|
# Minify all CSS and JS files in the output directory.
|
|
print("\nMinifying CSS and JS files...")
|
|
# css_minifier()
|
|
js_minifier(OUTPUT_DIR)
|
|
print("Build complete!")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|