Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add shiny_prerendered special comment via pandoc_include_args #2249

Merged
merged 12 commits into from
Feb 11, 2022

Conversation

atusy
Copy link
Collaborator

@atusy atusy commented Nov 24, 2021

instead of pandoc_variable_args and templates.

In this way, we can add <!-- HEAD_CONTENT --> even for custom templates, for sure.
If this is unlikely, I think we should document the need of this comment somewhere else not only in NEWS.md.

@atusy
Copy link
Collaborator Author

atusy commented Nov 24, 2021

Sorry, I worked on a wrong commit tree. I made fix and forced push.

Copy link
Member

@yihui yihui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks like a good idea to me. Thanks!

@cderv You can have another look.

@yihui yihui requested a review from cderv November 24, 2021 16:21
@cderv
Copy link
Collaborator

cderv commented Nov 24, 2021

Thanks, I'll have a look. We need to test this against learn basically (cc @gadenbuie ) and I need to check why we did it that way. I remember something with header-includes possibly not used or that the order matters.

Anyway, if we can do the change safely then that would be great to support custom template without having developers to know about this.

@gadenbuie
Copy link
Member

@atusy this is a very nice solution to use the widely used $header-includes$ pandoc template variable to ensure that custom templates don't need to add special treatment for shinyrmd (or shiny_prerendered) support. Thank you!

We added this originally because dynamic HTML dependencies in shiny Rmds were appearing higher up in the <head> element before other things, like jQuery and other dependencies. I think that as long as we ensure that the shiny-header.html is added to the end of the header_includes everything will work as expected. I tested this locally and it appears to work as expected with learnr.

We should also consider what happens if a user uses a template that already contains <!-- HEAD_CONTENT -->. The current behavior is to use the first of these that is found. So this change won't impact templates where a manually added <!-- HEAD_CONTENT --> appears before $header-includes$, just those where it appears after. I think the impact is likely to be small and the new behavior will probably be equally correct, but it's worth noting the change.

@atusy
Copy link
Collaborator Author

atusy commented Nov 25, 2021

The current behavior is to use the first of these that is found. So this change won't impact templates where a manually added <!-- HEAD_CONTENT --> appears before $header-includes$, just those where it appears after.

Oh yes, this is the good point, thank you @gadenbuie . I agree it is worth noting it.

Copy link
Collaborator

@cderv cderv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THanks @atusy.

I needed time to go back in time regarding the change I made initially and to fully grasp what this change means.

If I may go back to the why, what issue are we trying to solve here exactly ?

Change made in version 2.8 with #2064 was to bring a flexible mechanism.

  • Previous and default behavior was for shiny prerendered to include the HTML dependency content at the end of the <head>.
  • However, this was not enough for some template and we allowed to add the special comment anywhere in a custom template by using the variable set when shiny prerendered happens. This solved several issues in learnr because of how dependencies where loaded - some stuff in the head depending

With this PR, we are enforcing the later. This means that in all case shiny prerendered will insert its stuff at the same place as header-includes in the template.

Am I understanding correctly ? Do we agree on that ?
It seems the note made in NEWS is about that

If templates rely on the old behavior and require some contents between $header-includes$ and <!-- HEAD_CONTENT -->

but there is not always a <!-- HEAD_CONTENT -->, sometimes just the end of the <head>.

I think it is fine doing that as there are not a lot template using this feature, but I want to be sure. I know I spent time on the previous change so I want to check that we are doing things correctly and need to look into this a bit more.

Copy link
Collaborator

@cderv cderv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess my interrogation is do we still need the previous fix from #2064 that aimed to be an improvement over #1942, which ended up by doing

# The html template used to render the UI should contain the placeholder
# expected by shiny in `shiny:::renderPage()` which uses
# `htmltools::renderDocument`.
# If it is not present in the template, we add this placeholder at the end of
# the <head> element
if (!any(grepl(headContent <- "<!-- HEAD_CONTENT -->", html_with_deps, fixed = TRUE))) {
html_with_deps <- sub(
'</head>',
paste0('\n', headContent, '\n</head>'),
html_with_deps,
fixed = TRUE,
useBytes = TRUE)
Encoding(html_with_deps) <- "UTF-8"
}

With the solution of this PR, the special comment will always be added into the template (unless this is a template without $header-includes$ but I guess it is rare and probably won't work on other stuff).

Can we say that this PR offers a more generic solution to the initial problem of #1912 that the two previous PR tried to solve ?

I keep going back to the issue we are trying to solve because that is the most important: why do a change.

it seems like we can use your solution @atusy by always inserting the comment in header-includes. This means to always add the html deps by shiny at the same place as we regular documents. Seems quite right to me do that.

Does my thinking make sense ?

@gadenbuie
Copy link
Member

Can we say that this PR offers a more generic solution to the initial problem of #1912 that the two previous PR tried to solve ?

I agree with this. I think @atusy's approach here is quite elegant and addresses the issue that html dependencies would be loaded in different places when an Rmd is rendered as a static document vs when rendered as a shiny document. This PR would solve the problem for (almost) all pandoc templates.

With this PR, we'd now have three options:

  1. Do nothing and runtime: shiny will add <!-- HEAD_CONTENT --> in the right place.
  2. Manually add <!-- HEAD_CONTENT --> to the pandoc template, as long as it's above $header-includes$. This option would only be taken by the most diligent devs who follow rmarkdown very carefully. In other words, it's safe to assume very few people are using this feature.
  3. If all else fails, for some reason, then we put the html dependencies just before the closing </head>. Ideally this happens almost never, but it's reasonable to keep around just in case.

In summary, the justification for this PR is that it means that we're ensuring consistent behavior with and without runtime: [shiny | shinyrmd | shiny_prerendered] for all pandoc templates.

@cderv
Copy link
Collaborator

cderv commented Feb 9, 2022

Thanks - I am glad that confirms my understanding.

So @gadenbuie you would keep the current change from #2064 so the your case 3 works ? Only case I see this is for a document with no $header-includes$ - I think this case will never happens with rmarkdown and we would have some code just for this. I don't know if that is good in the long term - but I can document properly the code.

I guess 1 and 2 are enough, and mostly 1 will cover all case correctly. 2 will work as long as htmltools uses a sub() and not a gsub() 😅

Anyway, I am now convinced that this PR is a better solution for the initial issue. Thank you @atusy !

@atusy
Copy link
Collaborator Author

atusy commented Feb 11, 2022

Thank you @cderv for your neat discussion and @gadenbuie for your clear aswer!

I remember I dealt with this issue when I apply KaTeX in atusy/minidown.
However, I do not remember the detail and the reason why my template does not contain the <!-- HEAD_CONTENT -->...
Maybe I guessed this PR be merged promptly because of yihui's quick approval.
I should have kept the note by opening an issue in my repo...

@cderv
Copy link
Collaborator

cderv commented Feb 11, 2022

No worries, Opening issues and discussing in PR are great way to document things. We often remember that when we do not do it. 😅

I'll merge this now as it ends up being the right solution IMO - I was waiting for your last feedback.

I remember I dealt with this issue when I apply KaTeX in atusy/minidown.

rmarkdown now has support for several math engine using math_method argument - but you know that ! 😄

@atusy
Copy link
Collaborator Author

atusy commented Feb 11, 2022

rmarkdown now has support for several math engine using math_method argument - but you know that !

Of course, and supporting it is my milestone for minidown 0.5.0!

@cderv
Copy link
Collaborator

cderv commented Feb 11, 2022

Of course, and supporting it is my milestone for minidown 0.5.0!

#2304 could be even better for minidown maybe, to keep the HTML output without JS deps. Anyway ! Happy to help somehow if I missed something for easy integration in other format, but I think you have nothing really to do (unless you did some special treatment for Math already). Not the place to discuss though, I'll stop :)

@atusy
Copy link
Collaborator Author

atusy commented Feb 11, 2022

Thanks again!

@cderv cderv changed the title when is_shiny_prerendered(), add HEAD_CONTENT comment via pandoc_include_args add shiny_prerendered special comment via pandoc_include_args Feb 11, 2022
@cderv cderv merged commit 4c7b462 into rstudio:main Feb 11, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants