Publish icon indicating copy to clipboard operation
Publish copied to clipboard

Addition Nodes in HTML head

Open Ze0nC opened this issue 5 years ago • 13 comments

Hi @JohnSundell, sorry for requesting pulling so frequently. Here is one about an API change. The idea is in early stage and I want to discuss about it with you if you are interested.

About the change

  1. To add the additionalNodes argument in head function to specify addition nodes for pages.
  2. To add a whole-site additional Nodes for head.

I really appreciate the idea of "javascript-free", but sometimes we need to embed javascript in html head, such as when using Google Analytics. Therefore, I needed a way to add customized additional whole site nodes.

I have tried to write an extension in extension Node where Context == HTML.HeadContext in my own package. But I think it might be better to include the ability to add additional nodes in the official Publish repo.

usage example One example is adding Google Analytics to Publish, which requires script node in head. I have made demo plugin which uses the additionalWholeSiteHeadNodes property.

Another example is writing articles which need specific .js files. I have tried to show LaTeX equations with MathJax, so I need to add MathJaX script on some pages (not all). In this case the 'additionalNodes' argument is helpful.

Please consider the request when convienent. Cheers, Zhijin

Ze0nC avatar Jan 19 '20 07:01 Ze0nC

Oh, I was about to create same PR 👍 Right now we end up doing a pretty much the copy of the already prepared .head() which kinda sucks.

artur-ios-dev avatar Jan 19 '20 09:01 artur-ios-dev

Oh, I was about to create same PR 👍 Right now we end up doing a pretty much the copy of the already prepared .head() which kinda sucks.

It seems we all have this issue.

Since I want to keep using current code of my theme, I am using forked version of Publish and I have to keep it updated with upstream. It sometimes causes conflicts with other plugins.

Btw do you have any suggestion on improvement this implementation? I am wondering if there is a better way to do it...

Ze0nC avatar Jan 21 '20 17:01 Ze0nC

@Ze0nC I just made my own header function for now until this PR is merged.

artur-ios-dev avatar Jan 21 '20 17:01 artur-ios-dev

Oh, I was about to create same PR 👍 Right now we end up doing a pretty much the copy of the already prepared .head() which kinda sucks.

Off topic question: do you find any way to modify the content after generation of HTML, just like the Modifier in Plot.

Ze0nC avatar Jan 21 '20 17:01 Ze0nC

Off topic question: do you find any way to modify the content after generation of HTML, just like the Modifier in Plot.

I put a STRING_KEY in my article which I replace with the actual text while building page.

artur-ios-dev avatar Jan 21 '20 18:01 artur-ios-dev

Hi @JohnSundell ! I have finished my defense so now I have more free time on it!

After some considerations and trials I found it is hard for me to implement it without using global variable, so I would like to discuss with you.

First of all, we need to store the nodes in some place, and I have considered:

  • Node<HTML.DocumentContext>: This is bad since it is global. But it is the most convenient place to put global head nodes?
  • Website instance: Probably a good place, but I think 'Node' probably shouldn't appear here
  • PublishContext: Same with above.
  • HTMLFactory: Seems to be a good place. This is where HTML are generated.
  • Theme: Seems to be a good place?

I have considered for some days but haven't figured it out. Do you have some ideas/suggestions?

Cheers, Zhijin

Ze0nC avatar Feb 21 '20 12:02 Ze0nC

Hi @JohnSundell. I hope you are doing well recently. I committed a draft of new way to manage global head nodes of websites. Here are the changes:

  1. 'ConditionalHeadNode' has been added. It defines a var node: Node<HTML.HeadContext> with a var condition: (Location) -> Bool, and var target: String which is description of Website.
  2. 'ConditionalHeadNode' has a static variable var all: [ConditionalHeadNode], which holds all head nodes to add.
  3. 2 new functions were added to extension of Website to add and get the head nodes.

When the above change, it is possible to:

  1. Add global head nodes to certain websites.

  2. Add head nodes to certain pages of website.

However, it is not perfect:

  1. Should Website protocol has functions which deal with Node?

  2. Current way to identify target websites is by using description of websites. This is not safe and Swiftly. However due to limitation of my skills I didn't find a better to do it.

  3. Instead of var all: [ConditionalHeadNode], a dictionary might be better to store the nodes.

I hope this implementation is better then previous one.

Cheers, Zhijin

Ze0nC avatar Mar 02 '20 18:03 Ze0nC

why isn't this PR merged ?

yogeshmanghnani avatar Jul 14 '20 22:07 yogeshmanghnani

I hope this PR will be merged soon.

Malauch avatar Jan 03 '21 06:01 Malauch

I'm looking forward to this great feature! When can this PR be merged?

jjaychen1e avatar Oct 18 '21 02:10 jjaychen1e

So there's no implemented way of adding a Script tag at this moment?

t2ac32 avatar Dec 06 '21 22:12 t2ac32

I was looking for a solution to this as well, but I'm thinking it would be nice to have it as a plugin or additional publishing step. My reason for this is that I'd like to easily switch it on/off depending on whether I'm deploying for production or test.

dannys42 avatar Dec 30 '21 05:12 dannys42

@Ze0nC My approach to this problem is in PR-120. It's working with raw HTML, so not type-safe in any way, but allows someone to easily make a GoogleAnalytics plugin.

dannys42 avatar Dec 31 '21 07:12 dannys42