after_initialize do
require_relative "app/controllers/print_controller"
end
app/controllers/print_controller.rb
# frozen_string_literal: true
# HTTP Status codes: https://github.com/discourse/discourse/blob/main/lib/discourse.rb
class ::CountyFence::PrintController < ::ApplicationController
requires_plugin CountyFence::PLUGIN_NAME
def save_print
end
def list_prints
render json: { name: "donut", description: "delicious!" }
end
def get_print
end
end
Discourse::Application.routes.append do
post "/print" => "county_fence/print#save_print"
get "/print" => "county_fence/print#list_prints"
get "/print/:id" => "county_fence/print#get_print"
end
Is there a way I can get a blank page without the layout, navbars, or any CSS of the site? I want to use the Glimmer component, but none of the website styles are helpful in terms of producing a print page.
If its just styling for an actually printed page, and you don’t mind the navbar and extra stuff when viewing the page, you can use @media print CSS selector to change the styling when printing. Discourse already hides a lot of things during print (discourse/app/assets/stylesheets/common/printer-friendly.scss at main · discourse/discourse · GitHub). You can preview the page using print media simulation mode in firefox’s inspect mode. There should be an equivalent feature in chrome’s inspect mode.
If you need a complete blank canvas to work with, not just in the print mode but also in normal web browsing, you can use a bit of CSS trickery.
Suppose your glimmer component has a root div with id="print-component__root", we can let CSS check for its existence with a :has() selector (or just add/remove a class to body from the glimmer component lifecycle), and selectively apply styling.
body:has(#print-component__root) {
header,
.avatar,
.sidebar-wrapper,
... {
all: unset !important; // all: unset might be a bit too aggressive
display: none !important;
}
}
#print-component__root {
// normal styling
}
There might be a better, cleaner way that would actually remove the DOM elements, but the CSS is a good workaround to reset everything.
Just to make sure the issue is with loading the SCSS and not an issue with style rule I gave you, try adding a style without the :has() selector. Something like:
.sidebar-wrapper {
outline: 5px solid red;
}
I would also try restarting your rails server. I’ve had issues in the past where adding/removing register_asset calls would require me to do a full docker container reboot.
Put the code into index.scss to verify it’s not the @import statement
ran d/rake assets:clobber tmp:clear and d/rails s
Nothing so far is getting it to load.
Most other files cause an auto-reload in the browser. This one isn’t doing that. So I think that register_asset may be where the problem lies. I think register asset automatically looks in the assets folder? All of the examples I’m looking at indicate this is the case.
I found in the d/rails s logs: No such file or directory @ rb_sysopen - /src/app/assets/stylesheets/plugin-cf.scss.
So even though the plugin is symlinked into the /plugins folder as county-fence, and my plugin is explicitly named county-fence in plugins.rb, some code is reading the underlying directory name plugin-cf and making assumptions about what the compiled CSS name for my plugin is.
Is this a bug or a feature?
I think the moral of this story is do not under any circumstances name your plugin directory anything except the matching name of your plugin. A symlink named correctly is not sufficient.
EDIT: also register_asset "stylesheets/common/index.scss", plugin: "county-fence" is a workaround that forces the plugin name to be set correctly.
I’m having problems with the rules under body:has() being applied. They don’t appear to be updating in the asset compilation pipeline. I run d/rake assets:clobber tmp:clear and restart the server with d/rails s and they still don’t update.
For instance I can put body { background-color: red !important; } in the body:has() section and it doesn’t appear at all in the styles for the body element. It’s not just that it’s being overridden - it’s just not present at all in “styles” in the devtools.
When I place the same line of CSS outside of body:has() then it displays just fine.
document.querySelector("body:has(#print-root)") !== null in the browser console returns true. And some rules from body:has() are being applied.
I’m wondering if there could be rules in the asset generation pipeline that prevent these changes from coming through.
I think my go-to for this is just including styles directly in the glimmer component for the page. That’s the only thing I’ve tried that works consistently. And then I don’t have to muck with the conditional CSS rules.
The CSS compilation pipeline has been giving me no end of troubles - I’m finding it’s really inconsistent about refreshing, applying rules… things disappear and I don’t know why. I don’t know if this has something to do with running in a Docker container? I’ve now dispensed with my symlink to the plugins folder entirely - I believe that was causing problems with the Docker volume mount and file watching/recompilation. I can probably create a minimal repo to reproduce these problems… I’ll see if I can do that and get it published in the next few days.
An iframe being rendered from Stripe is now causing a blank page to be rendered at the bottom of my print layout. The iframe is hardcoded with display: block !important directly on the element.
I think I will work around this particular bug by deleting the iframe when this route loads… (By the way, Stripe is rendering a page wide div which detects all click events - which seems like quite a privacy invasion… I believe this is from the subscriptions plugin.)
But I’m looking into the future and foreseeing a long road of whack-a-mole troubleshooting on the print page. Anything in the future that introduces a new element in the layout, even if its not noticeably visible, could cause prints to malfunction.
It’s really not an ideal scenario for me to be inheriting the site layout for this route. Is there any way I can opt out, or set my own layout?