All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and Pydantic's HISTORY.md, and this project mostly adheres to Semantic Versioning.
- Multiblock pages using
multiblock_idare now required to provide a texture atassets/{namespace}/textures/multiblock/hexdoc/{path}.pngto render in the multiblock dropdown.
- Fixed a bug where multiblock pages using
multiblock_idwould generate invalid HTML or crash.
- Bumped minimum Hatch dependency to 1.16.5 to fix a crash in
hexdoc ci build.
- Improved the error message when attempting to load a language file with a malformed filename.
- The
langattribute inindex.htmlis now generated using langcodes instead of always defaulting toen.
- Fixed the language selector defaulting to "English (United States)" if the translation is missing.
- Fixed another issue with the web book being overwritten by a redirect page if the plugin version is removed from the site path.
- Added several new hooks to
ModPluginfor running code before/after the web book is generated.
- Fixed the web book being overwritten by a redirect page if the plugin version is removed from the site path.
- Added base classes
PageWithAccumulator,AccumulatorPage, etc. to allow consecutive pages of the same type to be merged into a single page.
CraftingPagenow extendsPageWithDoubleRecipeAccumulatorinstead ofPageWithDoubleRecipe.
- Fixed a validation failure when using Fabric Resource Conditions.
- Added proper support for Patchouli's config flag system. See https://hexdoc.hexxy.media for more details.
- A warning is now logged for entries with no pages.
- Fixed a bug that prevented books with empty entries from building.
- Fixed Markdown newlines being incorrectly escaped in some cases.
- Fixed incorrect Markdown escaping in
macros/styles.md.jinja.
- Added a page template for
patchouli:entitypages, by penguinencounter in #93.
- Added a page template for
patchouli:relationspages, by penguinencounter in #92.
- Changed animated texture type from linear to steps to fix glitched animations on page load, by penguinencounter in #89.
- Hotfix: Require
click<8.2.0to work around issue whereHEXDOC_RELEASEalways parses as True (#88).
- Add ru_ru localization for main hexdoc lang, by JustS-js in #87.
- Fix incorrect tag serialization caused by PydanticOrderedSet, which resulted in tags with optional entries failing to load in certain cases.
- Hotfix: Log a warning instead of failing the build when item NBT parsing fails.
- Update Pillow to 11.0, which should hopefully allow hexdoc to be used with Python 3.12+.
- ItemStack now uses nbtlib to parse NBT tags.
- Spotlight pages now use item names from NBT tags if set.
- Avoid adding a double title to spotlight pages with a title field.
- Fix broken environment variable loading by adding a dependency exclusion for Pydantic Settings v2.6.0 (see pydantic/pydantic-settings#445).
- New Jinja template filter:
hexdoc_smart_var- Can be used to allow runtime variable lookups based on values in
props.template.args. This is currently used by the custom navbar links feature.
- Can be used to allow runtime variable lookups based on values in
- Fix the root-level redirect not being generated in cases where there are no versioned books and no book exists for the default branch.
- Fix crash on startup by adding a dependency exclusion for Pydantic v2.9.0 (see pydantic/pydantic#10345).
- Allow adding custom links to the web book navbar (docs).
- Add missing handler for nested list styles (
$(li2),$(li3), etc). - Fix book links to other extension books on 1.19 and below (also fixes #75)
- Localize the "please don't sue us Microsoft" page footer (previously was hardcoded).
- Disable showing local variables in Typer pretty exceptions, since it produces a really absurd amount of output. Set a non-empty value for the environment variable
HEXDOC_TYPER_EXCEPTION_LOCALSto reenable it if you really want to.
- Update
zh_cntranslations, by @ChuijkYahus in #74.
- The internal hexdoc CI now automatically generates and deploys JSON Schema definitions for several Patchouli file types. See the documentation for more details.
- The
hexdoc.tomlfieldtextures.missingcan now be set tomissing = "*", allowing all textures to be missing. No other string values are currently supported. - The command
hexdoc mergenow creates an empty.nojekyllfile in the site root to disable Jekyll on GitHub Pages (since it's not necessary for hexdoc). Fixes #68. - Tentatively reenable Typer's pretty exceptions. Please open an issue if you notice any weird behaviour.
- Change the JSON Schema output path from
/schema/hexdocto/schema. - Several documentation improvements/fixes.
- The command
hexdoc render-modelswas accidentally configured to take a list of models as an option instead of an argument.
- Path resource dirs now support reading
.jarand.zipfiles.- Note: The resource folders (eg.
assets/) currently must be at the root of the archive.
- Note: The resource folders (eg.
- New glob resource dir type:
{ glob="mods/*.jar", exclude=["**/some_broken_mod.jar"] } - New texture config to print some errors instead of failing the build:
textures.strict - New command:
hexdoc render-models - Placeholders in
hexdoc.tomlmay now start with$to reference the root table (eg.{$modid}and{$.modid}are both valid).
- In
hexdoc.toml,default_langanddefault_branchare now optional, defaulting toen_usandmainrespectively. - Update minimum Pydantic version to
2.7.1. - Update Pyright version to
1.1.361.
- Add missing default values for some fields in
*.png.mcmeta.
- The internal hexdoc CI now automatically generates and deploys a JSON Schema definition for
hexdoc.toml. See the documentation for more details.
hexdoc servewill now fail immediately instead of retrying the build in non-release mode if an error occurs.- Update minimum Typer version to
0.12.
- Fix incorrect texture array size calculation when non-square images are used for block textures.
- Print stdout and stderr when shell commands fail (fixes #63).
- Improve the error message when GitHub Pages is not enabled.
- Support
.json5files in places other than I18n. Note that.flatten.json5is still only supported for I18n.
- New block rendering system, implemented entirely in Python! This replaces minecraft-render-py and removes hexdoc's Node.js dependency. Block renders should now be much closer to how items look in inventories ingame.
- Note: Animated models currently only render the first frame of the animation.
- Note:
minecraft-renderis still included as a dependency for backwards compatibility reasons. This will be removed in a future release.
- New command:
hexdoc render-model - New dependencies:
frozendict,moderngl[headless],moderngl-window - New
hexdoc.tomlfieldlang.{lang}for per-language configuration. Currently supported options includequietandignore_errors.
- Update
zh_cntranslations, by @ChuijkYahus in #69. - Blockstates are no longer taken into account when selecting block models to render.
- Deprecated the
--quiet-langCLI option. - Errors will now always be raised for all languages unless explicitly disabled in
hexdoc.toml. Previously, errors when rendering non-default languages would only fail the overall command in release mode.
⚠️ BREAKING: RemovedHexdocPythonResourceLoader, as it was only needed for the old rendering system.⚠️ BREAKING: RemovedHexdocAssetLoader.load_blockstatesandHexdocAssetLoader.renderer_loader. Several argument/return types have been changed fromIRenderClasstoBlockRenderer.- Removed
hexdoc render-blocksubcommands.
- hexdoc now uses a custom
sys.excepthookto hide unnecessary traceback frames, except in verbose mode. - New reusable workflow input
site-urlto help support non-Pages deployments.
- Adding spoilers to individual pages with the
advancementfield is now supported. - Use
uvinstead ofpipfor all reusable workflows. hexdoc ci buildnow attempts to read the site url fromHEXDOC_SITE_URLandGITHUB_PAGES_URLenvironment variables before querying the GitHub API.- "No translation in {lang} for key {key}" warnings are now only printed once per key for each language to reduce log spam.
- Web books will now generate a tree of redirects for categories, entries, and pages with anchors. These redirects include OpenGraph tags for generating Discord embeds.
- For example, https://hexcasting.hexxy.media/v/latest/main/1.19/en_us/basics now redirects to https://hexcasting.hexxy.media/v/latest/main/1.19/en_us#basics, and the Discord embed for the first link includes the category title "Getting Started".
- Added template variable
relative_site_url, which is a relative path to the root of the website from the current page.- For example, on the page
/v/latest/main/en_us,relative_site_urlwould be../../../...
- For example, on the page
- Added
HEXDOC_SUBDIRECTORYenvironment variable andsubdirectoryGitHub Actions option, for deploying a hexdoc book alongside other sites/pages. - Added the ability to print the installed hexdoc version with
hexdoc --version.
⚠️ BREAKING: Replaced thelink_basessystem withbook_linksto simplify/improve the link system.- This is what we use for constructing hrefs to internal and external categories/entries/pages. It's mostly only used internally, so this change hopefully won't have a big impact.
- Changed the Minecraft version in the dropdown to look like
Minecraft 1.19.2instead of just1.19.2. - Added more information to the hexdoc startup message, similar to what pytest prints.
- Updated minimum Pydantic version to
2.6.1. - Updated internal Pyright version from
1.1.343to1.1.345.- We have not updated to
1.1.346or higher because that version and1.1.350both introduce some type errors related to the lack of aTypeFormtype in Python. The new versions enforce that types likeUnionandAnnotatedshould not count astype, which is something that Pydantic and hexdoc are currently doing.
- We have not updated to
- #47: Concurrent builds overwrite each other because merge happens outside of the sequential part
⚠️ BREAKING: RemovedHexdocTypeAdapterbecauseTypeAdapteris now marked as final (and it never really worked properly anyway).
- Support for the rest of the default Patchouli page types, implemented by @SamsTheNerd in #53!
- Refactored recipe rendering for better reusability - see the default recipe page types for more details.
- Added
ModPlugin.default_rendered_templates_v2, which works the same asdefault_rendered_templatesbut gets the book and context as arguments.- This is meant to allow generating multi-file book structures instead of a single HTML document.
hexdoc.toml: Addedtemplate.render_from, which is a list of modids to include default rendered templates from, defaulting totemplate.include.- This can be used in conjunction with
template.includeto add a plugin's templates to the environment without rendering its default templates.
- This can be used in conjunction with
- The new version dropdown now only uses a submenu if there are at least 2 branches in a given version.
- Refactored
renderandsitemapout ofhexdoc.cli.utilsto more appropriate places. ModPlugin.default_rendered_templates(and_v2) may now returntuple[str, dict[str, Any]]as the dict value, where the string is the template to render and the dict contains extra arguments to pass to that template.
- Removed separators between versions in the new version dropdown to reduce visual clutter.
- Overflowing text with long item names in the new dropdown submenus.
- Incorrect logic for deciding which dropdown items to disable (ie. the current book version being viewed).
- "Unhandled tag" error for page types without a namespace (Patchouli adds
patchouli:if unspecified, but hexdoc didn't).
- Added
hexdoc_item, a Jinja filter that looks up anItemWithTexturefrom the item id.- Syntax:
{{ texture_macros.render_item("minecraft:stone"|hexdoc_item) }}
- Syntax:
- Updated the version dropdown! Versions are now grouped by Minecraft version, and branches are hidden behind a submenu to reduce clutter.
- This allows you to use the same mod version for different Minecraft versions, as long as the plugin version is different.
- To switch back to the old style, add
hide_dropdown_minecraft_version = trueto the[template.args]section of yourhexdoc.tomlfile.
- Added
BookPlugin, a base class for implementing alternative book systems. This is still heavily WIP, and there will be more breaking changes. We're planning to use this to implement Modonomicon support. - Internal: Added a Nox session to generate a dummy book for testing templates locally.
⚠️ BREAKING: Reworked book loading to support the newBookPluginsystem. This probably won't affect most users, but it is a breaking change.ModPlugin.jinja_template_rootmay now return a list of template roots.hexdoc_mod_pluginmay now return a list of plugins.hexdoc mergeandhexdoc ci mergewill now raise an error if trying to overwrite an existing version in release mode.- If you need to bypass this, either pass
--no-releasetohexdoc [ci] merge, or delete the.sitemap-marker.jsonfile(s) in the merge destination.
- If you need to bypass this, either pass
- The dropdown item for the current version is now disabled to give better feedback.
- Replaced our
JSONValuetype with an alias for Pydantic'sJsonValuetype.
⚠️ BREAKING: Removed reexports fromhexdoc.coreforAfter_1_20,Before_1_19, etc. They can still be imported fromhexdoc.core.compatif needed, but this makes the namespace a bit cleaner.
AttributeErrorwhen generating error message for a nonexistent resource dir.- Deserializing the union type
ItemWithTexture | TagWithTexturesometimes returnedTagWithTexturefor non-tag inputs.
- Implemented Pydantic models for all remaining vanilla recipes (other than
minecraft:special_*) and page types.- Templates for the new page models are still WIP, but the models should now expose all necessary data.
hexdoc.toml: Added support for directly specifyingpatchouli_booksdirectories inresource_dirs.- This is intended to support the modpack book layout, so the modid for this type of resource dir is always
patchouli. - Syntax:
resource_dirs = [ { patchouli_books="path/to/patchouli_books" }, ]
- This is intended to support the modpack book layout, so the modid for this type of resource dir is always
- The
I18nmissing translation log level is nowDEBUGwhenbook.i18nisFalse.
- Exception classname was not displayed in tagged union validation errors.
hexdoc.toml: Addedtextures.enabled. Set tofalseto disable texture rendering.hexdoc.toml: Addedmacrosfor adding local macro overrides, with the same structure as thebook.jsonfield.- Added an optional
propsfield toModPlugin. ImplementModPluginImplWithPropsinstead ofModPluginImplto get the props object when constructing your plugin. - Added
ModPlugin.update_jinja_env.
hexdoc.toml: Madetemplate.iconoptional.hexdoc.toml: Allowed settingtemplate.redirect={'!None'=true}to disable generating redirects inhexdoc build.ModPlugin.update_jinja_env(previouslyhexdoc_update_jinja_env) is now only called if the plugin's modid is intemplate.include.
⚠️ BREAKING: Removed thehexdoc_update_jinja_envhook.
- Added
link_overridesfield tohexdoc.toml, for patching broken inter-mod links. - Created a couple of Shields.io badges for hexdoc.
- Started keeping a changelog!
⚠️ BREAKING: Completely reworked the validation context system. Context is now a dict (returning to the Pydantic standard), and classes can now inherit fromhexdoc.utils.ValidationContextto get the methods.of()and.add_to_context().BookContextis no longer the god object for all validation context.- Moved Hatch to a required dependency, from
[pdoc]. - Slightly tweaked the page footer text.
- Fixed an issue that was preventing CI plugin builds from being copied to the Pages branch.
- Fixed category spoilers not taking external entries into account.