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
인쇄 모드뿐만 아니라 일반 웹 브라우저에서도 완전히 빈 캔버스가 필요하다면, CSS 트릭을 사용할 수 있습니다.
가령 glimmer 컴포넌트의 루트 div에 id="print-component__root"가 있다고 가정하면, :has() 선택자(또는 glimmer 컴포넌트 라이프사이클에서 body에 클래스를 추가/제거하는 방식)를 사용하여 CSS가 그 존재를 확인하고 선택적으로 스타일링을 적용할 수 있습니다.
body:has(#print-component__root) {
header,
.avatar,
.sidebar-wrapper,
... {
all: unset !important; // all: unset은 약간 과할 수 있음
display: none !important;
}
}
#print-component__root {
// 일반 스타일링
}
DOM 요소를 실제로 제거하는 더 나은, 더 깔끔한 방법이 있을 수 있지만, 모든 것을 초기화하기 위한 좋은 대안은 CSS입니다.
d/rake assets:clobber tmp:clear 및 d/rails s를 실행했습니다.
아직까지 로딩이 되지 않습니다.
대부분의 다른 파일은 브라우저에서 자동 재로드를 유발합니다. 하지만 이 파일은 그렇지 않습니다. 그래서 문제가 register_asset에 있는 것 같습니다. register_asset가 자동으로 assets 폴더를 조회하는 것 아닌가요? 제가 보고 있는 모든 예제에서는 그렇게 되어 있습니다.
d/rails s 로그에서 다음 오류를 발견했습니다: No such file or directory @ rb_sysopen - /src/app/assets/stylesheets/plugin-cf.scss.
즉, 플러그인이 /plugins 폴더에 county-fence라는 이름의 심볼릭 링크로 연결되어 있고, plugins.rb에서도 제 플러그인을 명시적으로 county-fence로 지정해 두었는데도, 어떤 코드는 실제 디렉터리 이름인 plugin-cf를 읽고 제 플러그인의 컴파일된 CSS 이름을 이에 맞춰 가정하고 있습니다.
이것은 버그인가요, 아니면 의도된 기능인가요?
제 생각에는 이 이야기의 교훈은 어떤 경우에도 플러그인 디렉터리 이름을 플러그인 이름과 일치하지 않는 이름으로 지정하지 말 것이라는 것입니다. 올바르게 이름이 지정된 심볼릭 링크만으로는 충분하지 않습니다.
수정: 또한 register_asset "stylesheets/common/index.scss", plugin: "county-fence"를 사용하면 플러그인 이름이 올바르게 설정되도록 강제하는 우회 방법입니다.
body:has() 아래 규칙이 적용되지 않는 문제가 있습니다. 에셋 컴파일 파이프라인에서 업데이트가 되지 않는 것 같습니다. d/rake assets:clobber tmp:clear를 실행하고 d/rails s로 서버를 재시작해도 여전히 업데이트되지 않습니다.
예를 들어 body:has() 섹션에 body { background-color: red !important; }를 추가해도 body 요소의 스타일에 전혀 반영되지 않습니다. 단순히 다른 스타일에 의해 오버라이드되는 것이 아니라, devtools의 “styles” 패널에 해당 규칙이 아예 존재하지 않습니다.
같은 CSS 라인을 body:has() 외부에 배치하면 정상적으로 표시됩니다.
브라우저 콘솔에서 document.querySelector("body:has(#print-root)") !== null은 true를 반환합니다. 그리고 body:has()의 일부 규칙은 적용되고 있습니다.
에셋 생성 파이프라인에 이러한 변경 사항이 반영되지 않도록 방지하는 규칙이 있는지 궁금합니다.
이 문제를 해결하기 위해 내가 주로 쓰는 방법은 페이지의 glimmer 컴포넌트에 스타일을 직접 포함시키는 것입니다. 제가 시도해 본 방법 중 일관되게 효과가 있는 것은 이것뿐입니다. 이렇게 하면 조건부 CSS 규칙을 가지고 헤매지 않아도 됩니다.
CSS 컴파일 파이프라인이 끝없는 문제를 일으키고 있습니다. 새로고침이나 규칙 적용이 정말로 일관성이 없네요. 스타일이 사라지는데 그 이유를 알 수 없습니다. 이게 Docker 컨테이너에서 실행하는 것과 관련이 있는지 모르겠습니다. 이제 플러그인 폴더에 대한 심볼릭 링크를 완전히 제거했습니다. Docker 볼륨 마운트와 파일 감시/재컴파일 문제를 일으키는 원인이었던 것 같습니다. 이 문제를 재현할 수 있는 최소한의 저장소를 만들 수 있을 것 같습니다… 며칠 안에 해볼 수 있는지 확인해서 공개해 보겠습니다.
Stripe에서 렌더링되는 iframe이 인쇄 레이아웃 하단에 빈 페이지가 표시되도록 만들고 있습니다. 해당 iframe은 요소에 display: block !important가 하드코딩되어 있습니다.
이 특정 버그는 해당 루트가 로드될 때 iframe을 삭제하는 방식으로 우회할 것 같습니다… (참고로 Stripe는 모든 클릭 이벤트를 감지하는 페이지 전체 너비의 div를 렌더링하고 있는데, 이는 상당한 프라이버시 침해로 보입니다. 구독 플러그인에서 비롯된 것으로 생각합니다.)
하지만 미래를 내다보았을 때, 인쇄 페이지에서 위장 게임을 하듯 끝없는 문제 해결이 이어질 것으로 예상됩니다. 레이아웃에 새로운 요소가 도입되는 경우, 눈에 띄지 않는 요소일지라도 인쇄 기능이 제대로 작동하지 않을 수 있습니다.
이 루트에 대해 사이트 레이아웃을 상속받는 것은 제게 이상적인 상황이 아닙니다. 이를 제외하거나 자체 레이아웃을 설정할 방법이 있을까요?