mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-02-09 03:09:38 +03:00
Allow page include system to include everything under a header level #3344
Open
opened 2026-02-05 06:25:04 +03:00 by OVERLORD
·
5 comments
No Branch/Tag Specified
development
further_theme_development
l10n_development
release
llm_only
vectors
v25-11
docker_env
drawio_rendering
user_permissions
ldap_host_failover
svg_image
prosemirror
captcha_example
fix/video-export
v25.12.3
v25.12.2
v25.12.1
v25.12
v25.11.6
v25.11.5
v25.11.4
v24.11.4
v25.11.3
v25.11.2
v25.11.1
v25.11
v25.07.3
v25.07.2
v25.07.1
v25.07
v25.05.2
v25.05.1
v25.05
v25.02.5
v25.02.4
v25.02.3
v25.02.2
v25.02.1
v25.02
v24.12.1
v24.12
v24.10.3
v24.10.2
v24.10.1
v24.10
v24.05.4
v24.05.3
v24.05.2
v24.05.1
v24.05
v24.02.3
v24.02.2
v24.02.1
v24.02
v23.12.3
v23.12.2
v23.12.1
v23.12
v23.10.4
v23.10.3
v23.10.2
v23.10.1
v23.10
v23.08.3
v23.08.2
v23.08.1
v23.08
v23.06.2
v23.06.1
v23.06
v23.05.2
v23.05.1
v23.05
v23.02.3
v23.02.2
v23.02.1
v23.02
v23.01.1
v23.01
v22.11.1
v22.11
v22.10.2
v22.10.1
v22.10
v22.09.1
v22.09
v22.07.3
v22.07.2
v22.07.1
v22.07
v22.06.2
v22.06.1
v22.06
v22.04.2
v22.04.1
v22.04
v22.03.1
v22.03
v22.02.3
v22.02.2
v22.02.1
v22.02
v21.12.5
v21.12.4
v21.12.3
v21.12.2
v21.12.1
v21.12
v21.11.3
v21.11.2
v21.11.1
v21.11
v21.10.3
v21.10.2
v21.10.1
v21.10
v21.08.6
v21.08.5
v21.08.4
v21.08.3
v21.08.2
v21.08.1
v21.08
v21.05.4
v21.05.3
v21.05.2
v21.05.1
v21.05
v21.04.6
v21.04.5
v21.04.4
v21.04.3
v21.04.2
v21.04.1
v21.04
v0.31.8
v0.31.7
v0.31.6
v0.31.5
v0.31.4
v0.31.3
v0.31.2
v0.31.1
v0.31.0
v0.30.7
v0.30.6
v0.30.5
v0.30.4
v0.30.3
v0.30.2
v0.30.1
v0.30.0
v0.29.3
v0.29.2
v0.29.1
v0.29.0
v0.28.3
v0.28.2
v0.28.1
v0.28.0
v0.27.5
v0.27.4
v0.27.3
v0.27.2
v0.27.1
v0.27
v0.26.4
v0.26.3
v0.26.2
v0.26.1
v0.26.0
v0.25.5
v0.25.4
v0.25.3
v0.25.2
v0.25.1
v0.25.0
v0.24.3
v0.24.2
v0.24.1
v0.24.0
v0.23.2
v0.23.1
v0.23.0
v0.22.0
v0.21.0
v0.20.3
v0.20.2
v0.20.1
v0.20.0
v0.19.0
v0.18.5
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.4
v0.17.3
v0.17.2
v0.17.1
v0.17.0
v0.16.3
v0.16.2
v0.16.1
v0.16.0
v0.15.3
v0.15.2
v0.15.1
v0.15.0
v0.14.3
v0.14.2
v0.14.1
v0.14.0
v0.13.1
v0.13.0
v0.12.2
v0.12.1
v0.12.0
v0.11.2
v0.11.1
v0.11.0
v0.10.0
v0.9.3
v0.9.2
v0.9.1
v0.9.0
v0.8.2
v0.8.1
v0.8.0
v0.7.6
v0.7.5
v0.7.4
v0.7.3
0.7.2
v.0.7.1
v0.7.0
v0.6.3
v0.6.2
v0.6.1
v0.6.0
v0.5.0
Labels
Clear labels
🎨 Design
📖 Docs Update
🐛 Bug
🐛 Bug
:cat2:🐈 Possible duplicate
💿 Database
☕ Open to discussion
💻 Front-End
🐕 Support
🚪 Authentication
🌍 Translations
🔌 API Task
🏭 Back-End
⛲ Upstream
🔨 Feature Request
🛠️ Enhancement
🛠️ Enhancement
🛠️ Enhancement
❤️ Happy feedback
🔒 Security
🔍 Pending Validation
💆 UX
📝 WYSIWYG Editor
🌔 Out of scope
🔩 API Request
:octocat: Admin/Meta
🖌️ View Customization
❓ Question
🚀 Priority
🛡️ Blocked
🚚 Export System
♿ A11y
🔧 Maintenance
> Markdown Editor
pull-request
Mirrored from GitHub Pull Request
No Label
🔨 Feature Request
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/BookStack#3344
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @WoosterInitiative on GitHub (Nov 15, 2022).
Describe the feature you'd like
It seems that a common use case for an include would be a header and everything underneath it. Say there's a page defined like so (using Markdown for easy text visibility):
Now lets say I want Heading 2 and everything underneath it on another page; currently, I don't see a "clean" way to do this. The only way I can think of is to grab the bookmark for each element (heading 2, subheadings 2.1 and 2.2, as well as the paragraph in 2.1 and the
olin 2.2).Describe the benefits this would bring to existing BookStack users
I believe this would be an intuitive and clean way for users to include content from one page on another page. I could be wrong, but it seems that this would be a common need for an include that wasn't a full page include.
Can the goal of this request already be achieved via other means?
Not that I can tell. Perhaps with Page Include Parse, but I don't see how.
I tried using the source code view and adding my own
<div>tag around the header and content I wanted with a custom id starting withbkmrk-, but the tag would move every time I saved the code.Otherwise, it's one block at a time. The other way would be to create a "dummy" page of the content and include it in both places, which I suppose works, but isn't as intuitive to me.
Have you searched for an existing open/closed issue?
How long have you been using BookStack?
0 to 6 months
Additional context
No response
@gaufde commented on GitHub (Jan 10, 2023):
+1 This seems like a critical feature for creating and maintaining complex documentation across books.
I also tried adding my own div, but just as you found that doesn't work. So far, the only work-arounds I have found are to either make a table with only one cell or to use a collapsible block to group content.
However, neither of these options are ideal since tables and collapsible blocks aren't really the correct elements for a job like this. Also, their UI on the back end makes the process clunky and unintuitive which is a huge problem when working with teams of people.
Seems to me like there are two routes that one could take for this feature. One is to add a new parameter to the embed feature that will automatically include all blocks until the next heading of the same level. This would of course need to be done in such a way that current embeds are not affected for backwards compatibility. The other option would be to add some sort of grouping element to the WSIWYG editor so that people can create custom content groupings for insertion. However, this option might promote bad writing habits and clutter up the UI.
I'm not sure I have the skills to do something like this, but if someone else does, @ssddanbrown are you open to accepting a PR for something like this?
@ssddanbrown commented on GitHub (Jan 11, 2023):
@gaufde Not really, at least not without a defined approach that would seem reasonable.
I really wouldn't want to add complexity to the editor/content structure just to support this lesser-used power-user subsystem.
Within v22.09 I added a logical theme even to specifically allow customization/extension of the page include system such as things, since there have been a few similar yet potentially conflicting requests. My intent is that such customization systems can be used to add such functionality as desired without us needing to support it in core. Some of the content parsing required for such a customization might be a little tricky (yet for sure possible) but I'm open to potentially easing that where it helps.
@gaufde commented on GitHub (Jan 11, 2023):
Fair enough. I still think there could be a good opportunity to add something like this in core, but I went ahead and implemented it myself using the logical theme event you both suggested.
I have made a couple of decisions that I think are quite clever, but they may not be to everyone's preference.
First, is that the heading you reference will not be included. Instead, only the content after the heading and up to the next heading of equal or greater importance will be included. This way, headings become like their own section dividers, and the sections they define are more portable without the heading itself.
Second, when you insert content into a page, you could get a gap in your heading structure where the inserted content uses headings that are all a couple levels smaller than what is on the parent page. This code will automatically adjust the heading tags of the inserted content to avoid this. Though keep in mind that after H5 the headings will be converted into strong tags.
@WoosterInitiative You should be able to copy all of my code into your functions.php file to get this feature working.
@ssddanbrown I'm not really a developer, but I muddle through projects like this when needed. If you have some time, I'd love to get some feedback from you on my implementation! Also, is there a central place for community members to share code snippets like this (maybe an Awesome-Bookstack repo)? Seems like we could all contribute to build a cool library of customizations.
Here is the code that I am using to modify the replacementHTML after Bookstack parses the page include:
And, here is the extension I made to the PageContent class:
@abr1x commented on GitHub (Jan 30, 2024):
@ssddanbrown this feature would be much appreciated if it were added to BookStack as a core feature. Because as @gaufde already said, this is quite an important feature if you maintain a more complex kind of documentation in BookStack without copying and pasting or micro segmenting to include whole pages
@Man-in-Black commented on GitHub (Oct 10, 2025):
I just want to pull this case up again.
I tried the code from @gaufde but it did not work sadly.
I've copied the code to the functions.php but I get the following error:
[2025-10-10 13:30:48] production.ERROR: Call to undefined method BookStack\Entities\Tools\PageContent::loadDocumentFromHtml() {"userId":3,"exception":"[object] (Error(code: 0): Call to undefined method BookStack\\Entities\\Tools\\PageContent::loadDocumentFromHtml() at /opt/bookstack/themes/foerster/functions.php:29)Maybe someone can help me fix this.