Docker Image - loading an additional PHP file #5148

Closed
opened 2026-02-05 09:44:25 +03:00 by OVERLORD · 6 comments
Owner

Originally created by @kristiandg on GitHub (Jan 25, 2025).

Attempted Debugging

  • I have read the debugging page

Searched GitHub Issues

  • I have searched GitHub for the issue.

Describe the Scenario

Good afternoon. I'm trying to add a bit of functionality that needs to be a combination of expansion code and a back-end "custom controller" (in theory, stored at /app/Http/Controllers). Is there any way to add my module, or store it elsewhere and tell BookStack to include it on load? Thanks.

Exact BookStack Version

v24.12.1

Log Content

n/a

Hosting Environment

Azure App Service (Docker Image) with Azure Storage mounted for off-board media content storage...

Originally created by @kristiandg on GitHub (Jan 25, 2025). ### Attempted Debugging - [x] I have read the debugging page ### Searched GitHub Issues - [x] I have searched GitHub for the issue. ### Describe the Scenario Good afternoon. I'm trying to add a bit of functionality that needs to be a combination of expansion code and a back-end "custom controller" (in theory, stored at /app/Http/Controllers). Is there any way to add my module, or store it elsewhere and tell BookStack to include it on load? Thanks. ### Exact BookStack Version v24.12.1 ### Log Content n/a ### Hosting Environment Azure App Service (Docker Image) with Azure Storage mounted for off-board media content storage...
OVERLORD added the 🐕 Support label 2026-02-05 09:44:25 +03:00
Author
Owner

@ssddanbrown commented on GitHub (Jan 25, 2025):

Hi @kristiandg,

The logical theme system allows back-end extension of app code:
https://github.com/BookStackApp/BookStack/blob/development/dev/docs/logical-theme-system.md

There are some events to register custom routes as shown here:
https://www.bookstackapp.com/blog/bookstack-release-v23-12/#logical-theme-system-events-to-register-routes

@ssddanbrown commented on GitHub (Jan 25, 2025): Hi @kristiandg, The logical theme system allows back-end extension of app code: https://github.com/BookStackApp/BookStack/blob/development/dev/docs/logical-theme-system.md There are some events to register custom routes as shown here: https://www.bookstackapp.com/blog/bookstack-release-v23-12/#logical-theme-system-events-to-register-routes
Author
Owner

@ssddanbrown commented on GitHub (Jan 25, 2025):

The recent discussion in #5430 also has some potentially relevant examples.

@ssddanbrown commented on GitHub (Jan 25, 2025): The recent discussion in #5430 also has some potentially relevant examples.
Author
Owner

@kristiandg commented on GitHub (Jan 25, 2025):

Well, after spending the past 5 hours on this, I'm officially throwing in the towel. I think I was on the right track with what I'm trying to do, I'm just not a coder really so already I've got one hand tied behind my back. lol

Is there a place where I can post a little bounty to have someone write what I'm wanting?

@kristiandg commented on GitHub (Jan 25, 2025): Well, after spending the past 5 hours on this, I'm officially throwing in the towel. I think I was on the right track with what I'm trying to do, I'm just not a coder really so already I've got one hand tied behind my back. lol Is there a place where I can post a little bounty to have someone write what I'm wanting?
Author
Owner

@ssddanbrown commented on GitHub (Jan 25, 2025):

What are you trying to do? Did you get the theme system running/active?

@ssddanbrown commented on GitHub (Jan 25, 2025): What are you trying to do? Did you get the theme system running/active?
Author
Owner

@kristiandg commented on GitHub (Jan 25, 2025):

What are you trying to do? Did you get the theme system running/active?

I'm pretty sure the Theme System is now in play because I accidentally forgot the PHP header at one point in my functions file, and that was now appearing as raw text at the top of the page (confirming it was reading that theme and processing it), and at random points during testing I'd do something to the file that would make the page formatting get really funky.

Ok, please don't make fun - as I said I'm not a coder. I was using ChatGPT to describe what I was trying to do, and I was relatively impressed (again, NOT a coder, so maybe easily impressed) at the various files it spun for me, but after a few hours, I ended up hitting a wall of going in circles with it during the diagnostics of trying to figure out the failure...

What I'm trying to do is this (and it's in 2 parts):
Dynamic Image:

  • Create a Placeholder ( it created: ![[dynamic-logo/logo]] ) for an image within a book (like, a company logo), and based on the host-part of the URL you used to access the BookStack server, that would dictate what logo to display in the book (basically, branding the book).

  • In order for it to get the details necessary to determine which image to use, the code first looks at the host-part , then queries a piece of middleware I have deployed for another project. The middleware requires an auth key, which for safety reasons, I've added to my .env as "UE_MIDDLEWARE_API_KEY" (and not put directly in the code).

  • The query it assembles is basically submitting that hostpart to the middleware, in a body like this:
    portalRootSubstring: "{{HOSTPARTGOESHERE}}"  //domain name reqType: "getVanityCertsByPortalRoot"

  • The response looks like this:
    "theGlobalObject": { "current_domain": "Developer", "sub_domain": "Developer", "sub_user": "1001", "sub_reseller": "Developer", "sub_scope": "Super User", "sub_site": null, "scope_mode": "admin", "omp_level": "navigation_reseller", "sub_email": "{{REDACTED}}", "sub_name": "SuperUser Developer Test", "sub_time_zone": "US/Eastern", "sub_uri": "{{REDACTED}}", "server_name": "{{REDACTED}}"},
    and what we care about is: "sub_reseller": "Developer" (we now know Developer)

Once we have that sub_reseller value, we then retrieve the image from this assembled URL, inserting the sub_reseller's value as part of the image retrieval query:
`https://{{REDACTED}}/ns-api/?object=image&action=read&filename=portal_main_top_left.png&territory={{sub_resellerValue}}

  • That becomes the image for the page, based on the host part used to visit the BookStack server. (I hadn't gotten into what that might look like when you print/download a book, because that's the server rendering that PDF, but if I couldn't do it there too, I'd just disable printing/downloading.
  • It would also be nice if the image were cached on the local user's browser so we weren't downloading the image every time a book was opened (as it will be the same image because it's branding the pages in the book).

What I deployed, did recognize the markdown placeholder, but it ended up just displaying the raw text.

Dynamic Video Watermark

  • Using the same query logic above, that same image file being used as a watermark in a defined position of any video files shown on the site. Meaning, if you drop a Youtube link on a page, this little watermark (a miniature version of the logo, which has transparency already, is partially transparent in the lower right corner of the video file as you watch it)

I'm not even sure if the Video Watermark is possible. I mean, I know it's possible in general, but not sure BookStack is capable of that one, but I sure was going to try. lol

@kristiandg commented on GitHub (Jan 25, 2025): > What are you trying to do? Did you get the theme system running/active? I'm pretty sure the Theme System is now in play because I accidentally forgot the PHP header at one point in my functions file, and that was now appearing as raw text at the top of the page (confirming it was reading that theme and processing it), and at random points during testing I'd do something to the file that would make the page formatting get really funky. Ok, please don't make fun - as I said I'm not a coder. I was using ChatGPT to describe what I was trying to do, and I was relatively impressed (again, NOT a coder, so maybe easily impressed) at the various files it spun for me, but after a few hours, I ended up hitting a wall of going in circles with it during the diagnostics of trying to figure out the failure... What I'm trying to do is this (and it's in 2 parts): **Dynamic Image:** - Create a Placeholder ( it created: `![[dynamic-logo/logo]]` ) for an image within a book (like, a company logo), and based on the host-part of the URL you used to access the BookStack server, that would dictate what logo to display in the book (basically, branding the book). - In order for it to get the details necessary to determine which image to use, the code first looks at the host-part , then queries a piece of middleware I have deployed for another project. The middleware requires an auth key, which for safety reasons, I've added to my .env as "UE_MIDDLEWARE_API_KEY" (and not put directly in the code). - The query it assembles is basically submitting that hostpart to the middleware, in a body like this: `portalRootSubstring: "{{HOSTPARTGOESHERE}}"  //domain name reqType: "getVanityCertsByPortalRoot"` - The response looks like this: `"theGlobalObject": { "current_domain": "Developer", "sub_domain": "Developer", "sub_user": "1001", "sub_reseller": "Developer", "sub_scope": "Super User", "sub_site": null, "scope_mode": "admin", "omp_level": "navigation_reseller", "sub_email": "{{REDACTED}}", "sub_name": "SuperUser Developer Test", "sub_time_zone": "US/Eastern", "sub_uri": "{{REDACTED}}", "server_name": "{{REDACTED}}"},` and what we care about is: `"sub_reseller": "Developer"` (we now know **Developer**) Once we have that sub_reseller value, we then retrieve the image from this assembled URL, inserting the sub_reseller's value as part of the image retrieval query: `https://{{REDACTED}}/ns-api/?object=image&action=read&filename=portal_main_top_left.png&territory={{sub_resellerValue}} - That becomes the image for the page, based on the host part used to visit the BookStack server. (I hadn't gotten into what that might look like when you print/download a book, because that's the server rendering that PDF, but if I couldn't do it there too, I'd just disable printing/downloading. - It would also be nice if the image were cached on the local user's browser so we weren't downloading the image every time a book was opened (as it will be the same image because it's branding the pages in the book). What I deployed, did recognize the markdown placeholder, but it ended up just displaying the raw text. **Dynamic Video Watermark** - Using the same query logic above, that same image file being used as a watermark in a defined position of any video files shown on the site. Meaning, if you drop a Youtube link on a page, this little watermark (a miniature version of the logo, which has transparency already, is partially transparent in the lower right corner of the video file as you watch it) I'm not even sure if the Video Watermark is possible. I mean, I know it's possible in general, but not sure BookStack is capable of that one, but I sure was going to try. lol
Author
Owner

@ssddanbrown commented on GitHub (Sep 3, 2025):

Since this support request is quite old, and for a specific external scenario, I'm going to close this off.

@ssddanbrown commented on GitHub (Sep 3, 2025): Since this support request is quite old, and for a specific external scenario, I'm going to close this off.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#5148