From 73807869ff8a36cd31cd835cc6e2d8e281d74f55 Mon Sep 17 00:00:00 2001
From: x222 <113437965+rsnx222@users.noreply.github.com>
Date: Wed, 26 Feb 2025 22:37:46 +0000
Subject: [PATCH 1/4] Fix path handling issues in MkDocs generation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
gen_pages.py: Ensured source_dir is always an absolute Path to prevent NoneType errors.
name_conversion.py: Fixed an issue where channel['path'] could be None, ensuring valid path operations.
rules.py: Prevented NoneType errors when formatting Discord channel links by defaulting to a safe path.
page_generator.py: Fixed relative_to() path errors by resolving absolute paths and falling back if paths donβt match.
---
gen_pages.py | 6 ++++--
site_builder/formatter/rules.py | 3 ++-
site_builder/name_conversion.py | 6 ++++--
site_builder/page_generator.py | 13 ++++++++++++-
4 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/gen_pages.py b/gen_pages.py
index e8351d6a59..9ead2f8aeb 100644
--- a/gen_pages.py
+++ b/gen_pages.py
@@ -31,7 +31,9 @@
# 'afk/**/*.txt'
# ])
-name_converter = NameConverter(settings.name_convert, settings.files.source_dir)
+source_dir = Path(settings.files.source_dir).resolve() if settings.files.source_dir else Path("docs").resolve()
+
+name_converter = NameConverter(settings.name_convert, source_dir)
+page_generator = PageGenerator(files, name_converter, source_dir)
-page_generator = PageGenerator(files, name_converter, settings.files.source_dir)
page_generator.generate_pages()
diff --git a/site_builder/formatter/rules.py b/site_builder/formatter/rules.py
index 7130310f5b..5843e7a517 100644
--- a/site_builder/formatter/rules.py
+++ b/site_builder/formatter/rules.py
@@ -169,7 +169,8 @@ def format_content(content):
# path = f"{os.path.dirname(txt_path)}/{name}"
# link = f"[#{name}](../../{path})"
name = channel['name']
- txt_file = Path(channel['path'])
+ txt_file = Path(channel['path']) if channel.get('path') else Path("docs/unknown.txt")
+
# todo: work-around relative links, check if absolute links work
relative_path = '../' * (len(DiscordChannelID.CUR_FILE.parts) - 1) + txt_file.with_suffix('').as_posix()
link = f"[#{name}]({relative_path})"
diff --git a/site_builder/name_conversion.py b/site_builder/name_conversion.py
index 8047b2022b..193187ab20 100644
--- a/site_builder/name_conversion.py
+++ b/site_builder/name_conversion.py
@@ -31,8 +31,10 @@ def __init__(self, settings: NameConvertSettings, source_dir: Path):
self.__category_settings = AliasStore('category', settings.category)
self.__forum_alias = AliasStore('forum', settings.forum)
self.__word_alias = AliasStore('word', settings.word)
- self.__channel_alias = {source_dir / channel['path']: channel['name'] for channel in
- DiscordChannelID.CHANNEL_LOOKUP.values()}
+ self.__channel_alias = {
+ source_dir / Path(channel['path']) if channel.get('path') else source_dir: channel['name']
+ for channel in DiscordChannelID.CHANNEL_LOOKUP.values()
+ }
self.__extra_channel_alias = AliasStore('extra-channel-alias', settings.extra_channel)
def channel(self, source_file: Path):
diff --git a/site_builder/page_generator.py b/site_builder/page_generator.py
index eaef899457..bb1222af61 100644
--- a/site_builder/page_generator.py
+++ b/site_builder/page_generator.py
@@ -29,7 +29,18 @@ def generate_pages(self):
output_file = source_file.with_suffix('.md')
self.generate_page(source_file, output_file, channel_name)
- self.__update_nav(source_file.relative_to(self.__source_output_dir).parent, output_file, channel_name)
+
+ source_file_absolute = source_file.resolve()
+ source_output_absolute = self.__source_output_dir.resolve()
+
+ try:
+ relative_source = source_file_absolute.relative_to(source_output_absolute)
+ except ValueError:
+ logger.warning(f"Cannot compute relative path for {source_file_absolute}. Using absolute path instead.")
+ relative_source = source_file_absolute # Fallback to absolute path
+
+ self.__update_nav(relative_source.parent, output_file, channel_name)
+
self.__nav.update_mkdocs_nav()
From 2a7eee96fddc68e6acc780a329bebf17e9213533 Mon Sep 17 00:00:00 2001
From: x222 <113437965+rsnx222@users.noreply.github.com>
Date: Fri, 28 Feb 2025 11:11:59 +0000
Subject: [PATCH 2/4] 1/2 - Simplified nav and landing page guides
Still needs "first child" logic when you click on category
---
docs/pvme-guides.md | 55 ++++++++++++++++
docs/stylesheets/extra.css | 27 ++++++++
mkdocs.yml | 39 +++++++----
site_builder/navigation.py | 115 ++++++++++++++++++++++++++++-----
site_builder/page_generator.py | 47 +++++++-------
structure_settings.yml | 90 ++++++++++++--------------
6 files changed, 276 insertions(+), 97 deletions(-)
create mode 100644 docs/pvme-guides.md
diff --git a/docs/pvme-guides.md b/docs/pvme-guides.md
new file mode 100644
index 0000000000..1ef1052895
--- /dev/null
+++ b/docs/pvme-guides.md
@@ -0,0 +1,55 @@
+---
+hide:
+ - navigation
+ - toc
+
+hide_actions: true
+---
+# PVM Guides
+
+
\ No newline at end of file
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
index b9928dee2a..59ea7bb099 100644
--- a/docs/stylesheets/extra.css
+++ b/docs/stylesheets/extra.css
@@ -65,4 +65,31 @@ p {
/* Hide navigation emojis when the category is opened */
.md-nav__link .nav-emoji {
display: none;
+}
+
+.md-typeset .grid {
+ grid-gap: 1rem;
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
+}
+
+.md-typeset .grid.cards>ul>li {
+ padding: 0;
+}
+
+.md-typeset .grid li > a {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ color: var(--md-primary-bg-color);
+ padding: 0.8rem;
+}
+
+.md-typeset .grid li:hover > a {
+ color: var(--md-primary-fg-color);
+}
+
+
+.md-typeset .grid h2 {
+ margin: 0;
}
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 5232726fa0..b56fe463bf 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -13,14 +13,14 @@ theme:
custom_dir: overrides
favicon: assets/logo.ico
features:
- - navigation.instant
- navigation.tabs
- navigation.tabs.sticky
+ - navigation.instant
+ - navigation.sections
+ - navigation.expand
+ - navigation.path
- search.suggest
- search.highlight
- # - search.share
- - navigation.top
- # - navigation.indexes
- announce.dismiss
- content.action.edit
palette:
@@ -33,10 +33,8 @@ theme:
icon: material/weather-sunny
name: Switch to dark mode
-
plugins:
- search
-#- git-revision-date-localized
- macros
- gen-files:
scripts:
@@ -50,7 +48,8 @@ markdown_extensions:
- pymdownx.emoji
- admonition
- footnotes
-# - pymdownx.extra (markdown formatting in HTMl blocks)
+ - attr_list
+ - md_in_html
extra_css:
- stylesheets/extra.css
@@ -61,9 +60,23 @@ extra_javascript:
- javascripts/discordInvite.js
nav:
- - index.md
- - About:
- - Info: about/info.md
- - Keyboard Shortcuts: about/shortcuts.md
- - How The Site Works: about/workings.md
- - Changelog: about/changelog.md
\ No newline at end of file
+ - Home: index.md
+ - Getting Started:
+ - New to PvM: new-to-pvm
+ - New to Bossing: new-to-bossing
+ - Invention & Perks: invention-and-perks
+ - PVME Guides:
+ - Guides Home: pvme-guides.md
+ - Basic Guides: basic-guides
+ - RS3 Full Boss Guides: rs3-full-boss-guides
+ - AFK Methods: afk
+ - Combat Achievements: combat-achievements
+ - Slayer Guides: slayer
+ - One Tick Guides: one-tick-guides
+ - Strategy:
+ - DPM Advice: dpm-advice
+ - Upgrade Paths: upgrading-info
+ - Miscellaneous:
+ - PVME Mastery Roles: get-involved
+ - About PVME: about
+ - Editor Resources: editor-resources
diff --git a/site_builder/navigation.py b/site_builder/navigation.py
index be11b20334..6aadeb97b0 100644
--- a/site_builder/navigation.py
+++ b/site_builder/navigation.py
@@ -1,24 +1,109 @@
-from typing import List, Union, Tuple
+import yaml
+import logging
+from typing import List
+from pathlib import Path
+from collections import defaultdict
+logging.basicConfig(level=logging.DEBUG, format="%(levelname)s:%(name)s:%(message)s")
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
-class NavStructure(dict):
- def __setitem__(self, keys: List[str], value: Union[Tuple[str, str], str]):
- cur = self
- for key in keys:
- cur = cur.setdefault(key, {})
- cur[value[0]] = value[1]
+# Load NAV structure from mkdocs.yml
+def load_nav_from_mkdocs():
+ mkdocs_path = Path("mkdocs.yml")
+ with mkdocs_path.open("r", encoding="utf-8") as file:
+ config = yaml.safe_load(file)
+ return config.get("nav", [])
+HARDCODED_NAV = load_nav_from_mkdocs()
class NavInterface:
- def __init__(self, mkdocs_nav):
+ def __init__(self, mkdocs_nav, source_files, name_converter):
+ if mkdocs_nav is None:
+ raise ValueError("Error: MkDocs navigation is None. Ensure 'nav:' is properly initialized.")
+
self.__nav = mkdocs_nav
- self.__structure = NavStructure()
+ self.__source_files = source_files
+ self.__name_converter = name_converter
+ self.__structure = defaultdict(lambda: defaultdict(list))
- def add_item(self, category_name, forum_name, channel_name, output_file):
- keys = [category_name]
+ def add_item(self, category_name: str, forum_name: str, channel_name: str, output_file: str):
+ """Ensures Level 2 appears first, then nests Level 3 pages under it properly."""
if forum_name:
- keys.append(forum_name)
- self.__structure[keys] = channel_name, output_file
+ self.__structure[category_name][forum_name].append({channel_name: output_file})
+ else:
+ self.__structure[category_name][channel_name] = output_file
+
+ def find_first_guide(self, category_folder, mkdocs_files):
+ """Finds the first available markdown file inside a given category."""
+ logger.debug(f"π Searching for guides in category: {category_folder}")
+
+ # Normalize category path for comparison
+ expected_prefix = f"pvme-guides/{category_folder}/"
+
+ # Retrieve and sort relevant markdown files
+ md_files = sorted(
+ [file.src_path for file in mkdocs_files if file.src_path.startswith(expected_prefix) and file.src_path.endswith(".md")]
+ )
+
+ logger.debug(f"π Found {len(md_files)} markdown files for {category_folder}: {md_files}")
+
+ return md_files[0] if md_files else None # Return first guide if found
+
+ def rebuild_nav(self, mkdocs_files):
+ """Ensures 'PVME Guides' appears with its subcategories and actual guides."""
+ logger.debug("π Rebuilding MkDocs Navigation")
+
+ nav = []
+
+ # Force all paths to use forward slashes to avoid Windows path issues
+ all_md_files = [file.src_path.replace("\\", "/") for file in mkdocs_files if file.src_path.endswith(".md")]
+ logger.debug(f"π ALL MkDocs Markdown Files: {all_md_files}")
+
+ # Load PVME Guides categories from HARDCODED_NAV
+ pvme_guides_section = None
+ for section in HARDCODED_NAV:
+ if isinstance(section, dict) and "PVME Guides" in section:
+ category_entries = section["PVME Guides"]
+ logger.debug(f"π Found PVME Guides Categories: {category_entries}")
+
+ # Initialize PVME Guides with its landing page
+ pvme_guides_section = {"PVME Guides": []}
+
+ for entry in category_entries:
+ if isinstance(entry, dict):
+ for category, folder in entry.items():
+ # Find all markdown files within the category (recursive scan)
+ category_guides = sorted(
+ [file for file in all_md_files if file.startswith(f"pvme-guides/{folder}/")]
+ )
+
+ if category_guides:
+ # Append actual guides under each category
+ pvme_guides_section["PVME Guides"].append({category: category_guides})
+ logger.debug(f"π Added {len(category_guides)} guides under '{category}'.")
+ else:
+ # Ensure empty categories still exist as placeholders
+ pvme_guides_section["PVME Guides"].append({category: folder})
+ logger.warning(f"β οΈ No guides found for '{category}', keeping as placeholder.")
+
+ elif isinstance(entry, str):
+ # Ensure the landing page is added first
+ pvme_guides_section["PVME Guides"].insert(0, entry)
+ logger.debug(f"π Added PVME Guides Landing Page: {entry}")
+
+ break # We only need to process PVME Guides once
+
+ if pvme_guides_section:
+ nav.append(pvme_guides_section)
+ else:
+ logger.warning("β οΈ PVME Guides structure not found, skipping.")
+
+ # Preserve other sections
+ for section in HARDCODED_NAV:
+ if isinstance(section, dict) and "PVME Guides" not in section:
+ nav.append(section)
- def update_mkdocs_nav(self):
- self.__nav.extend([{key: value} for key, value in self.__structure.items()])
+ self.__nav.clear()
+ self.__nav.extend(nav)
+ logger.debug(f"β
Final Navigation Structure:\n{self.__nav}")
diff --git a/site_builder/page_generator.py b/site_builder/page_generator.py
index bb1222af61..ad849a29bc 100644
--- a/site_builder/page_generator.py
+++ b/site_builder/page_generator.py
@@ -1,19 +1,15 @@
import logging
from typing import List
from pathlib import Path
-
import mkdocs_gen_files
-
from site_builder.navigation import NavInterface
from site_builder.formatter.rules import DiscordChannelID
from site_builder.raw_message_parser import get_raw_messages
from site_builder.formatter.message_formatter import MessageFormatter
from site_builder.name_conversion import NameConverter
-
logger = logging.getLogger(__name__)
-
class PageGenerator:
def __init__(self, source_files: List[Path], name_converter: NameConverter, source_output_dir: Path):
self.__source_output_dir = source_output_dir
@@ -21,36 +17,37 @@ def __init__(self, source_files: List[Path], name_converter: NameConverter, sour
self.__name_converter = name_converter
mkdocs_process = mkdocs_gen_files.FilesEditor.current()
- self.__nav = NavInterface(mkdocs_process.config.nav)
+ mkdocs_nav = getattr(mkdocs_process.config, "nav", None)
+
+ if mkdocs_nav is None:
+ raise ValueError("Error: MkDocs navigation is not initialized. Ensure 'nav:' is defined in mkdocs.yml before running.")
+
+ self.__nav = NavInterface(mkdocs_nav, self.__source_files, self.__name_converter)
def generate_pages(self):
+ mkdocs_process = mkdocs_gen_files.FilesEditor.current()
+ mkdocs_files = mkdocs_process.files
+
for source_file in self.__source_files:
channel_name = self.__name_converter.channel(source_file)
output_file = source_file.with_suffix('.md')
self.generate_page(source_file, output_file, channel_name)
- source_file_absolute = source_file.resolve()
- source_output_absolute = self.__source_output_dir.resolve()
+ self.__update_nav(source_file.parent, output_file, channel_name)
- try:
- relative_source = source_file_absolute.relative_to(source_output_absolute)
- except ValueError:
- logger.warning(f"Cannot compute relative path for {source_file_absolute}. Using absolute path instead.")
- relative_source = source_file_absolute # Fallback to absolute path
-
- self.__update_nav(relative_source.parent, output_file, channel_name)
-
-
- self.__nav.update_mkdocs_nav()
+ # Rebuild navigation after processing all pages
+ self.__nav.rebuild_nav(mkdocs_files)
@staticmethod
def generate_page(source_file: Path, output_file: Path, channel_name):
- logger.debug(f"formatting: {output_file}")
+ logger.debug(f"π Generating page: {output_file}")
+
+ output_file.parent.mkdir(parents=True, exist_ok=True)
- # todo: work-around relative links, check if absolute links work
DiscordChannelID.CUR_FILE = output_file
- formatted_channel = f""
+
+ formatted_channel = f"# {channel_name}\n\n"
for raw_message in get_raw_messages(source_file.read_text('utf-8')):
message_formatter = MessageFormatter(raw_message)
message_formatter.format()
@@ -60,8 +57,14 @@ def generate_page(source_file: Path, output_file: Path, channel_name):
file.write(formatted_channel)
def __update_nav(self, category_forum_path: Path, output_file, channel_name):
+ """Ensures correct Level 2 & 3 nesting in navigation."""
category, *forum = category_forum_path.parts
category_name = self.__name_converter.category(category)
- forum_name = self.__name_converter.forum(forum[0]) if len(forum) > 0 else None
+ forum_name = self.__name_converter.forum(forum[0]) if forum else None
+
+ corrected_path = output_file.as_posix()
+
+ if corrected_path.startswith("pvme-guides/pvme-guides"):
+ corrected_path = corrected_path.replace("pvme-guides/pvme-guides", "pvme-guides", 1)
- self.__nav.add_item(category_name, forum_name, channel_name, output_file.as_posix())
\ No newline at end of file
+ self.__nav.add_item(category_name, forum_name, channel_name, corrected_path)
diff --git a/structure_settings.yml b/structure_settings.yml
index 3466662713..6922d95272 100644
--- a/structure_settings.yml
+++ b/structure_settings.yml
@@ -1,45 +1,29 @@
files:
includes:
- - getting-started/quick-start.txt
- - getting-started/how-to-use-pvme.txt
- - getting-started/interface-guide.txt
- - getting-started/early-moneymaking-ideas.txt
- - getting-started/noncombat-skilling-guides.txt
-
+ # Getting Started
+ - getting-started/**/*.txt
- new-to-pvm/**/*.txt
-
- new-to-bossing/**/*.txt
+ # Invention & Perks
- invention-and-perks/**/*.txt
-
- - miscellaneous-information/**/*.txt
-
- - upgrading-info/upgrade-order/*.txt
- - upgrading-info/**/*.txt
- - dpm-advice/**/*.txt
-
- - afk/afk-overview.txt
- - afk/**/*.txt
-
- - basic-guides/**/*.txt
-
- - rs3-full-boss-guides/**/*.txt
+ # Guides
+ - basic-guides/**/*.{txt,md}
+ - rs3-full-boss-guides/**/*.{txt,md}
+ - afk/**/*.{txt,md}
+ - combat-achievements/**/*.{txt,md}
+ - slayer/**/*.{txt,md}
+ - one-tick-guides/**/*.{txt,md}
- - slayer/overview-of-slayer.txt
- - slayer/block-prefer-list.txt
- - slayer/ultimate-slayer.txt
- - slayer/miscellaneous-slayer.txt
- - slayer/**/*.txt
+ # Strategy
+ - dpm-advice/**/*.{txt,md}
+ - upgrading-info/**/*.{txt,md}
- - get-involved/mastery-requirements.txt
- - get-involved/feats-requirements.txt
-
- - editor-resources/intro-to-editing.txt
- - editor-resources/intro-to-editing-continued.txt
- - editor-resources/editor-tools/*.txt
- - editor-resources/editor-references/*.txt
- - editor-resources/github-tutorials/*.txt
+ # Miscellaneous
+ - get-involved/**/*.{txt,md}
+ - editor-resources/**/*.{txt,md}
+ - miscellaneous-information/**/*.{txt,md}
excludes:
- navigation/**/*.txt
@@ -52,26 +36,38 @@ files:
- get-involved/editor-entry.txt
- .github/**/*
-# uncategorized:
-# - '**/*.txt'
-
name_convert:
category:
+ getting-started:
+ alias: Getting Started
+ new-to-pvm:
+ alias: New to PvM
+ new-to-bossing:
+ alias: New to Bossing
invention-and-perks:
- alias: perks
- emoji: "689509250946695292"
- miscellaneous-information:
- alias: miscellaneous
- upgrading-info:
- alias: upgrades
- slayer:
- emoji: "797896049548066857"
+ alias: Invention & Perks
+ basic-guides:
+ alias: Basic Guides
rs3-full-boss-guides:
- alias: full boss guides
+ alias: RS3 Full Boss Guides
+ afk:
+ alias: AFK Methods
+ combat-achievements:
+ alias: Combat Achievements
+ slayer:
+ alias: Slayer Guides
+ one-tick-guides:
+ alias: One Tick Guides
+ dpm-advice:
+ alias: Strategy
+ upgrading-info:
+ alias: Strategy
get-involved:
- alias: mastery
+ alias: PVME Mastery Roles
editor-resources:
- alias: editor info
+ alias: Editor Resources
+ miscellaneous-information:
+ alias: Miscellaneous
extra_channel:
AFK Commander Zilyana Hard Mode: afk commander zilyana hm
From 24ad62b4efcd0fbf1dd39d65726ad6c2cf1ccfff Mon Sep 17 00:00:00 2001
From: x222 <113437965+rsnx222@users.noreply.github.com>
Date: Fri, 28 Feb 2025 13:47:15 +0000
Subject: [PATCH 3/4] 1/2 continued
renamed section to "boss guides" to avoid confusion with pvme-guides
---
...vme-guides.md => boss-guides-directory.md} | 3 +-
mkdocs.yml | 10 +++---
site_builder/navigation.py | 34 +++++++++----------
site_builder/page_generator.py | 7 ++--
4 files changed, 26 insertions(+), 28 deletions(-)
rename docs/{pvme-guides.md => boss-guides-directory.md} (97%)
diff --git a/docs/pvme-guides.md b/docs/boss-guides-directory.md
similarity index 97%
rename from docs/pvme-guides.md
rename to docs/boss-guides-directory.md
index 1ef1052895..1fe39e8048 100644
--- a/docs/pvme-guides.md
+++ b/docs/boss-guides-directory.md
@@ -1,11 +1,10 @@
---
hide:
- - navigation
- toc
hide_actions: true
---
-# PVM Guides
+# Boss Guides - Directory
diff --git a/mkdocs.yml b/mkdocs.yml
index b56fe463bf..fdb9ecc3e8 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -14,11 +14,8 @@ theme:
favicon: assets/logo.ico
features:
- navigation.tabs
- - navigation.tabs.sticky
- navigation.instant
- - navigation.sections
- - navigation.expand
- - navigation.path
+ - navigation.indexes
- search.suggest
- search.highlight
- announce.dismiss
@@ -65,11 +62,12 @@ nav:
- New to PvM: new-to-pvm
- New to Bossing: new-to-bossing
- Invention & Perks: invention-and-perks
- - PVME Guides:
- - Guides Home: pvme-guides.md
+ - Boss Guides:
+ - Boss Guide Directory: boss-guides-directory.md
- Basic Guides: basic-guides
- RS3 Full Boss Guides: rs3-full-boss-guides
- AFK Methods: afk
+ - Other Guides:
- Combat Achievements: combat-achievements
- Slayer Guides: slayer
- One Tick Guides: one-tick-guides
diff --git a/site_builder/navigation.py b/site_builder/navigation.py
index 6aadeb97b0..74e41b26b9 100644
--- a/site_builder/navigation.py
+++ b/site_builder/navigation.py
@@ -51,7 +51,7 @@ def find_first_guide(self, category_folder, mkdocs_files):
return md_files[0] if md_files else None # Return first guide if found
def rebuild_nav(self, mkdocs_files):
- """Ensures 'PVME Guides' appears with its subcategories and actual guides."""
+ """Ensures 'Boss Guides' appears with its subcategories and actual guides."""
logger.debug("π Rebuilding MkDocs Navigation")
nav = []
@@ -60,15 +60,15 @@ def rebuild_nav(self, mkdocs_files):
all_md_files = [file.src_path.replace("\\", "/") for file in mkdocs_files if file.src_path.endswith(".md")]
logger.debug(f"π ALL MkDocs Markdown Files: {all_md_files}")
- # Load PVME Guides categories from HARDCODED_NAV
- pvme_guides_section = None
+ # Load Boss Guides categories from HARDCODED_NAV
+ boss_guides_section = None
for section in HARDCODED_NAV:
- if isinstance(section, dict) and "PVME Guides" in section:
- category_entries = section["PVME Guides"]
- logger.debug(f"π Found PVME Guides Categories: {category_entries}")
+ if isinstance(section, dict) and "Boss Guides" in section:
+ category_entries = section["Boss Guides"]
+ logger.debug(f"π Found Boss Guides Categories: {category_entries}")
- # Initialize PVME Guides with its landing page
- pvme_guides_section = {"PVME Guides": []}
+ # Initialize Boss Guides with its landing page
+ boss_guides_section = {"Boss Guides": []}
for entry in category_entries:
if isinstance(entry, dict):
@@ -80,28 +80,28 @@ def rebuild_nav(self, mkdocs_files):
if category_guides:
# Append actual guides under each category
- pvme_guides_section["PVME Guides"].append({category: category_guides})
+ boss_guides_section["Boss Guides"].append({category: category_guides})
logger.debug(f"π Added {len(category_guides)} guides under '{category}'.")
else:
# Ensure empty categories still exist as placeholders
- pvme_guides_section["PVME Guides"].append({category: folder})
+ boss_guides_section["Boss Guides"].append({category: folder})
logger.warning(f"β οΈ No guides found for '{category}', keeping as placeholder.")
elif isinstance(entry, str):
# Ensure the landing page is added first
- pvme_guides_section["PVME Guides"].insert(0, entry)
- logger.debug(f"π Added PVME Guides Landing Page: {entry}")
+ boss_guides_section["Boss Guides"].insert(0, entry)
+ logger.debug(f"π Added Boss Guides Landing Page: {entry}")
- break # We only need to process PVME Guides once
+ break # We only need to process Boss Guides once
- if pvme_guides_section:
- nav.append(pvme_guides_section)
+ if boss_guides_section:
+ nav.append(boss_guides_section)
else:
- logger.warning("β οΈ PVME Guides structure not found, skipping.")
+ logger.warning("β οΈ Boss Guides structure not found, skipping.")
# Preserve other sections
for section in HARDCODED_NAV:
- if isinstance(section, dict) and "PVME Guides" not in section:
+ if isinstance(section, dict) and "Boss Guides" not in section:
nav.append(section)
self.__nav.clear()
diff --git a/site_builder/page_generator.py b/site_builder/page_generator.py
index ad849a29bc..357ac21750 100644
--- a/site_builder/page_generator.py
+++ b/site_builder/page_generator.py
@@ -48,7 +48,7 @@ def generate_page(source_file: Path, output_file: Path, channel_name):
DiscordChannelID.CUR_FILE = output_file
formatted_channel = f"# {channel_name}\n\n"
- for raw_message in get_raw_messages(source_file.read_text('utf-8')):
+ for raw_message in get_raw_messages(source_file.read_text('utf-8')):
message_formatter = MessageFormatter(raw_message)
message_formatter.format()
formatted_channel += str(message_formatter.formatted_message)
@@ -64,7 +64,8 @@ def __update_nav(self, category_forum_path: Path, output_file, channel_name):
corrected_path = output_file.as_posix()
- if corrected_path.startswith("pvme-guides/pvme-guides"):
- corrected_path = corrected_path.replace("pvme-guides/pvme-guides", "pvme-guides", 1)
+ # Update path logic for "Boss Guides" and renamed directories
+ if corrected_path.startswith("boss-guides/boss-guides"):
+ corrected_path = corrected_path.replace("boss-guides/boss-guides", "boss-guides", 1)
self.__nav.add_item(category_name, forum_name, channel_name, corrected_path)
From 2268447814e2db3afc897e859011948fffdf6a62 Mon Sep 17 00:00:00 2001
From: x222 <113437965+rsnx222@users.noreply.github.com>
Date: Sat, 1 Mar 2025 07:41:31 +0000
Subject: [PATCH 4/4] 2/3 just need to nest guides inside sections now
---
docs/boss-guides/afk.md | 5 +
docs/boss-guides/basic-guides.md | 5 +
docs/boss-guides/combat-achievements.md | 5 +
.../index.md} | 16 +--
docs/boss-guides/one-tick-guides.md | 5 +
docs/boss-guides/rs3-full-boss-guides.md | 5 +
docs/boss-guides/slayer.md | 5 +
mkdocs.yml | 17 ++-
site_builder/navigation.py | 106 ++++++++----------
site_builder/page_generator.py | 91 +++++++++++++--
structure_settings.yml | 20 +---
11 files changed, 175 insertions(+), 105 deletions(-)
create mode 100644 docs/boss-guides/afk.md
create mode 100644 docs/boss-guides/basic-guides.md
create mode 100644 docs/boss-guides/combat-achievements.md
rename docs/{boss-guides-directory.md => boss-guides/index.md} (75%)
create mode 100644 docs/boss-guides/one-tick-guides.md
create mode 100644 docs/boss-guides/rs3-full-boss-guides.md
create mode 100644 docs/boss-guides/slayer.md
diff --git a/docs/boss-guides/afk.md b/docs/boss-guides/afk.md
new file mode 100644
index 0000000000..cadce56ee7
--- /dev/null
+++ b/docs/boss-guides/afk.md
@@ -0,0 +1,5 @@
+---
+title: Redirecting...
+---
+
+
\ No newline at end of file
diff --git a/docs/boss-guides/basic-guides.md b/docs/boss-guides/basic-guides.md
new file mode 100644
index 0000000000..2a8233a3d8
--- /dev/null
+++ b/docs/boss-guides/basic-guides.md
@@ -0,0 +1,5 @@
+---
+title: Redirecting...
+---
+
+
\ No newline at end of file
diff --git a/docs/boss-guides/combat-achievements.md b/docs/boss-guides/combat-achievements.md
new file mode 100644
index 0000000000..3e7c4deb52
--- /dev/null
+++ b/docs/boss-guides/combat-achievements.md
@@ -0,0 +1,5 @@
+---
+title: Redirecting...
+---
+
+
\ No newline at end of file
diff --git a/docs/boss-guides-directory.md b/docs/boss-guides/index.md
similarity index 75%
rename from docs/boss-guides-directory.md
rename to docs/boss-guides/index.md
index 1fe39e8048..0e37e54f4e 100644
--- a/docs/boss-guides-directory.md
+++ b/docs/boss-guides/index.md
@@ -4,47 +4,47 @@ hide:
hide_actions: true
---
-# Boss Guides - Directory
+# Boss & Slayer Guides - Directory
-
-
+
Basic Guides
Just getting into with PVM? Start here!
-
-
-
Full Boss Guides
+
+ Full Boss & Slayer Guides
From presets to rotations, learn how to maximise your kills per hour at any boss in the game.
-
-
+
AFK Methods
Need some downtime? Don't want to actively kill a boss? A large number of bosses can be killed AFK.
-
-
+
Combat Achievements
CAs can be really challenging! We're compiling the best of the best here.
-
-
+
Slayer Guides
Ultimate Slayer is one heck of a grind - discover ways to take on various mobs.
-
-
+
One Tick Guides
Want fast kills and set new personal bests?
diff --git a/docs/boss-guides/one-tick-guides.md b/docs/boss-guides/one-tick-guides.md
new file mode 100644
index 0000000000..e396c90dac
--- /dev/null
+++ b/docs/boss-guides/one-tick-guides.md
@@ -0,0 +1,5 @@
+---
+title: Redirecting...
+---
+
+
\ No newline at end of file
diff --git a/docs/boss-guides/rs3-full-boss-guides.md b/docs/boss-guides/rs3-full-boss-guides.md
new file mode 100644
index 0000000000..831daf66c3
--- /dev/null
+++ b/docs/boss-guides/rs3-full-boss-guides.md
@@ -0,0 +1,5 @@
+---
+title: Redirecting...
+---
+
+
\ No newline at end of file
diff --git a/docs/boss-guides/slayer.md b/docs/boss-guides/slayer.md
new file mode 100644
index 0000000000..50ab7846f7
--- /dev/null
+++ b/docs/boss-guides/slayer.md
@@ -0,0 +1,5 @@
+---
+title: Redirecting...
+---
+
+
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index fdb9ecc3e8..f1db05fae7 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -62,15 +62,14 @@ nav:
- New to PvM: new-to-pvm
- New to Bossing: new-to-bossing
- Invention & Perks: invention-and-perks
- - Boss Guides:
- - Boss Guide Directory: boss-guides-directory.md
- - Basic Guides: basic-guides
- - RS3 Full Boss Guides: rs3-full-boss-guides
- - AFK Methods: afk
- - Other Guides:
- - Combat Achievements: combat-achievements
- - Slayer Guides: slayer
- - One Tick Guides: one-tick-guides
+ - Boss & Slayer Guides:
+ - Guide Directory: boss-guides/index.md
+ - Basic Guides: boss-guides/basic-guides.md
+ - RS3 Full Boss Guides: boss-guides/rs3-full-boss-guides.md
+ - AFK Methods: boss-guides/afk.md
+ - Combat Achievements: boss-guides/combat-achievements.md
+ - Slayer Guides: boss-guides/slayer.md
+ - One Tick Guides: boss-guides/one-tick-guides.md
- Strategy:
- DPM Advice: dpm-advice
- Upgrade Paths: upgrading-info
diff --git a/site_builder/navigation.py b/site_builder/navigation.py
index 74e41b26b9..6b3292c16e 100644
--- a/site_builder/navigation.py
+++ b/site_builder/navigation.py
@@ -27,6 +27,10 @@ def __init__(self, mkdocs_nav, source_files, name_converter):
self.__name_converter = name_converter
self.__structure = defaultdict(lambda: defaultdict(list))
+ def get_nav_structure(self):
+ """Returns the internal navigation structure."""
+ return self.__nav
+
def add_item(self, category_name: str, forum_name: str, channel_name: str, output_file: str):
"""Ensures Level 2 appears first, then nests Level 3 pages under it properly."""
if forum_name:
@@ -34,76 +38,56 @@ def add_item(self, category_name: str, forum_name: str, channel_name: str, outpu
else:
self.__structure[category_name][channel_name] = output_file
- def find_first_guide(self, category_folder, mkdocs_files):
- """Finds the first available markdown file inside a given category."""
- logger.debug(f"π Searching for guides in category: {category_folder}")
-
- # Normalize category path for comparison
- expected_prefix = f"pvme-guides/{category_folder}/"
-
- # Retrieve and sort relevant markdown files
- md_files = sorted(
- [file.src_path for file in mkdocs_files if file.src_path.startswith(expected_prefix) and file.src_path.endswith(".md")]
- )
-
- logger.debug(f"π Found {len(md_files)} markdown files for {category_folder}: {md_files}")
-
- return md_files[0] if md_files else None # Return first guide if found
-
def rebuild_nav(self, mkdocs_files):
- """Ensures 'Boss Guides' appears with its subcategories and actual guides."""
+ """Ensures that sub-pages are correctly collected and nested under their respective sections."""
logger.debug("π Rebuilding MkDocs Navigation")
nav = []
# Force all paths to use forward slashes to avoid Windows path issues
- all_md_files = [file.src_path.replace("\\", "/") for file in mkdocs_files if file.src_path.endswith(".md")]
+ all_md_files = [
+ Path(file.src_path).as_posix() for file in mkdocs_files if Path(file.src_path).suffix == ".md"
+ ]
logger.debug(f"π ALL MkDocs Markdown Files: {all_md_files}")
- # Load Boss Guides categories from HARDCODED_NAV
- boss_guides_section = None
+ # Iterate through all sections in HARDCODED_NAV
for section in HARDCODED_NAV:
- if isinstance(section, dict) and "Boss Guides" in section:
- category_entries = section["Boss Guides"]
- logger.debug(f"π Found Boss Guides Categories: {category_entries}")
-
- # Initialize Boss Guides with its landing page
- boss_guides_section = {"Boss Guides": []}
-
- for entry in category_entries:
- if isinstance(entry, dict):
- for category, folder in entry.items():
- # Find all markdown files within the category (recursive scan)
- category_guides = sorted(
- [file for file in all_md_files if file.startswith(f"pvme-guides/{folder}/")]
- )
-
- if category_guides:
- # Append actual guides under each category
- boss_guides_section["Boss Guides"].append({category: category_guides})
- logger.debug(f"π Added {len(category_guides)} guides under '{category}'.")
- else:
- # Ensure empty categories still exist as placeholders
- boss_guides_section["Boss Guides"].append({category: folder})
- logger.warning(f"β οΈ No guides found for '{category}', keeping as placeholder.")
-
- elif isinstance(entry, str):
- # Ensure the landing page is added first
- boss_guides_section["Boss Guides"].insert(0, entry)
- logger.debug(f"π Added Boss Guides Landing Page: {entry}")
-
- break # We only need to process Boss Guides once
-
- if boss_guides_section:
- nav.append(boss_guides_section)
- else:
- logger.warning("β οΈ Boss Guides structure not found, skipping.")
-
- # Preserve other sections
- for section in HARDCODED_NAV:
- if isinstance(section, dict) and "Boss Guides" not in section:
- nav.append(section)
-
+ if isinstance(section, dict):
+ # Look for the "Boss & Slayer Guides" section and process it
+ if "Boss & Slayer Guides" in section:
+ category_entries = section["Boss & Slayer Guides"]
+ logger.debug(f"π Found Boss & Slayer Guides Categories: {category_entries}")
+
+ boss_guides_section = {"Boss & Slayer Guides": []}
+
+ for entry in category_entries:
+ if isinstance(entry, dict):
+ for category, folder in entry.items():
+ # Convert section name to lowercase and replace spaces with hyphens for folder path
+ category_folder = category.lower().replace(" ", "-")
+
+ # Find all markdown files for this category and subfolders (excluding 'index.md' for redirects)
+ category_guides = sorted(
+ [file for file in all_md_files if f"pvme-guides/{category_folder}/" in file and "index.md" not in file]
+ )
+
+ # Check if category guides are found, if so, add them
+ if category_guides:
+ boss_guides_section["Boss & Slayer Guides"].append({category: category_guides})
+ logger.debug(f"π Added {len(category_guides)} guides under '{category}'.")
+ else:
+ # Ensure empty categories still appear as placeholders
+ boss_guides_section["Boss & Slayer Guides"].append({category: folder})
+ logger.warning(f"β οΈ No guides found for '{category}', keeping as placeholder.")
+
+ # Add the Boss & Slayer Guides section to the nav
+ nav.append(boss_guides_section)
+
+ # For all other sections (excluding "Boss & Slayer Guides"), just add them to the nav
+ else:
+ nav.append(section)
+
+ # Rebuild the final nav structure, preserving the order defined in mkdocs.yml
self.__nav.clear()
self.__nav.extend(nav)
logger.debug(f"β
Final Navigation Structure:\n{self.__nav}")
diff --git a/site_builder/page_generator.py b/site_builder/page_generator.py
index 357ac21750..2d67a8edaf 100644
--- a/site_builder/page_generator.py
+++ b/site_builder/page_generator.py
@@ -33,7 +33,6 @@ def generate_pages(self):
output_file = source_file.with_suffix('.md')
self.generate_page(source_file, output_file, channel_name)
-
self.__update_nav(source_file.parent, output_file, channel_name)
# Rebuild navigation after processing all pages
@@ -58,14 +57,90 @@ def generate_page(source_file: Path, output_file: Path, channel_name):
def __update_nav(self, category_forum_path: Path, output_file, channel_name):
"""Ensures correct Level 2 & 3 nesting in navigation."""
- category, *forum = category_forum_path.parts
- category_name = self.__name_converter.category(category)
- forum_name = self.__name_converter.forum(forum[0]) if forum else None
+ # Strip 'pvme-guides' from the path to get the actual category
+ path_parts = category_forum_path.parts[1:] # Skip the 'pvme-guides' part
+ category_name = path_parts[0].lower() # This should be the category like 'afk'
+ forum_name = path_parts[1].lower() if len(path_parts) > 1 else None # Get the forum if it exists
corrected_path = output_file.as_posix()
- # Update path logic for "Boss Guides" and renamed directories
- if corrected_path.startswith("boss-guides/boss-guides"):
- corrected_path = corrected_path.replace("boss-guides/boss-guides", "boss-guides", 1)
+ # Access the navigation structure
+ nav_structure = self.__nav.get_nav_structure()
+
+ # Keep a reference to the original structure
+ original_nav_structure = self.__store_original_nav_structure(nav_structure)
+
+ # Preprocess nav structure to trim paths before "/" and remove ".md"
+ self.__preprocess_nav_structure(nav_structure)
+
+ # logger.debug(f"π Preprocessed nav structure: {nav_structure}")
+
+ # Iterate over the nav structure and look for the correct category and subcategory
+ for section in nav_structure:
+ if isinstance(section, dict):
+ for section_name, subcategories in section.items():
+ # Log each section and its subcategories for inspection
+ # logger.debug(f"π Inspecting section: {section_name} with subcategories: {subcategories}")
+
+ # Check if the category matches
+ if category_name in [item.lower() if isinstance(item, str) else item.lower() for sub_category in subcategories for item in (sub_category.values() if isinstance(sub_category, dict) else [sub_category])]:
+ logger.debug(f"β
Found category: {category_name}")
+
+ # Iterate through subcategories in this section (level 2)
+ if isinstance(subcategories, list):
+ for sub_category in subcategories:
+ if isinstance(sub_category, dict):
+ for sub_category_name, sub_category_path in sub_category.items():
+ # Normalize subcategory name and path
+ sub_category_path_normalized = sub_category_path.lower().replace(" ", "-")
+
+ # Check if the path matches
+ if sub_category_path_normalized == category_name:
+ # Retrieve the original section name from the stored reference
+ original_section_name = original_nav_structure[section_name]
+
+ # Add the page to this subcategory using the original structure
+ original_section_name.append({channel_name: corrected_path})
+ logger.debug(f"π Added page under subcategory: '{sub_category_name}'")
+ return
+ else:
+ logger.warning(f"β οΈ Subcategory '{forum_name}' not found in '{category_name}'")
+ elif isinstance(sub_category, str): # Handle case when sub_category is just a string (without being inside a dictionary)
+ if sub_category.lower() == category_name:
+ # Directly add to subcategory
+ sub_category.append({channel_name: corrected_path})
+ logger.debug(f"π Added page under subcategory: '{sub_category}'")
+ return
+
+ else:
+ logger.warning(f"β οΈ Subcategories for '{category_name}' are not in the expected format.")
+
+ # If no matching category was found
+ logger.warning(f"β οΈ No matching category found for '{category_name}' in the nav structure.")
+
+ def __store_original_nav_structure(self, nav_structure):
+ """Store the original structure for later reference."""
+ original_structure = {}
+ for section in nav_structure:
+ if isinstance(section, dict):
+ for section_name, subcategories in section.items():
+ # Store original section names
+ original_structure[section_name] = subcategories
+ return original_structure
+
+ def __preprocess_nav_structure(self, nav_structure):
+ """Preprocess nav structure to trim paths and remove extensions"""
+ for section in nav_structure:
+ if isinstance(section, dict):
+ for section_name, subcategories in section.items():
+ # If section has subcategories (nested dictionaries)
+ if isinstance(subcategories, list):
+ for sub_category in subcategories:
+ for sub_category_name, sub_category_path in sub_category.items():
+ # If path contains "/", remove everything before it and also remove ".md"
+ sub_category_path = sub_category_path.split('/')[1] if '/' in sub_category_path else sub_category_path
+ sub_category_path = sub_category_path.replace(".md", "").lower()
+
+ # Update subcategory path
+ sub_category[sub_category_name] = sub_category_path
- self.__nav.add_item(category_name, forum_name, channel_name, corrected_path)
diff --git a/structure_settings.yml b/structure_settings.yml
index 6922d95272..df7671fd40 100644
--- a/structure_settings.yml
+++ b/structure_settings.yml
@@ -67,22 +67,4 @@ name_convert:
editor-resources:
alias: Editor Resources
miscellaneous-information:
- alias: Miscellaneous
-
- extra_channel:
- AFK Commander Zilyana Hard Mode: afk commander zilyana hm
- AFK General Graardor Hard Mode: afk general graardor hm
- AFK Kree-arra Hard Mode: afk kree'arra hm
- AFK K'ril Tsutsaroth Hard Mode: afk k'ril tsutsaroth hm
-
- word:
- osrs: OSRS
- gwd1: GWD1
- gwd2: GWD2
- pvm: PvM
- afk: AFK
- ed1: ED1
- ed2: ED2
- ed3: ED3
- dpm: DPM
- hm: HM
+ alias: Miscellaneous
\ No newline at end of file