From 59988f46a19981a6615d4475e38b702b3414049a Mon Sep 17 00:00:00 2001 From: Jezen Thomas Date: Fri, 23 Aug 2019 13:49:33 +0200 Subject: [PATCH 1/3] Add jsAttributesHandler This adds `jsAttributesHandler` to run arbitrary Handler code before building the attributes map for the script tag generated by `widgetFile`. This is useful if you need to add a randomised nonce value to that tag. Closes https://github.com/yesodweb/yesod/issues/1621 --- yesod-core/ChangeLog.md | 5 +++++ yesod-core/src/Yesod/Core/Class/Yesod.hs | 21 +++++++++++++++++++-- yesod-core/yesod-core.cabal | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/yesod-core/ChangeLog.md b/yesod-core/ChangeLog.md index 2d1a6e75..3108ec47 100644 --- a/yesod-core/ChangeLog.md +++ b/yesod-core/ChangeLog.md @@ -1,5 +1,10 @@ # ChangeLog for yesod-core +## 1.6.16 + +* Add `jsAttributesHandler` to run arbitrary Handler code before building the + attributes map for the script tag generated by `widgetFile` [#1622](https://github.com/yesodweb/yesod/pull/1622) + ## 1.6.15 * Move `redirectToPost` JavaScript form submission from HTML element to diff --git a/yesod-core/src/Yesod/Core/Class/Yesod.hs b/yesod-core/src/Yesod/Core/Class/Yesod.hs index df8d195b..b6886c70 100644 --- a/yesod-core/src/Yesod/Core/Class/Yesod.hs +++ b/yesod-core/src/Yesod/Core/Class/Yesod.hs @@ -249,6 +249,17 @@ class RenderRoute site => Yesod site where jsAttributes :: site -> [(Text, Text)] jsAttributes _ = [] + -- | Same as @jsAttributes@ but allows you to run arbitrary Handler code + -- + -- This is useful if you need to add a randomised nonce value to the script + -- tag generated by @widgetFile@. If you use both this function and + -- @jsAttributes@, the two attribute maps will be merged, favouring the + -- keys from @jsAttributes@ in case of a collision. + -- + -- @since 1.6.16 + jsAttributesHandler :: HandlerFor site [(Text, Text)] + jsAttributesHandler = pure [] + -- | Create a session backend. Returning 'Nothing' disables -- sessions. If you'd like to change the way that the session -- cookies are created, take a look at @@ -520,7 +531,9 @@ defaultCsrfMiddleware = defaultCsrfSetCookieMiddleware . defaultCsrfCheckMiddlew widgetToPageContent :: Yesod site => WidgetFor site () -> HandlerFor site (PageContent (Route site)) -widgetToPageContent w = HandlerFor $ \hd -> do +widgetToPageContent w = do + jsAttrsFromHandler <- jsAttributesHandler + HandlerFor $ \hd -> do master <- unHandlerFor getYesod hd ref <- newIORef mempty unWidgetFor w WidgetData @@ -531,6 +544,10 @@ widgetToPageContent w = HandlerFor $ \hd -> do let title = maybe mempty unTitle mTitle scripts = runUniqueList scripts' stylesheets = runUniqueList stylesheets' + jsAttrs = + let jsAttrsStatic = Map.fromList (jsAttributes master) + jsAttrsDynamic = Map.fromList jsAttrsFromHandler + in Map.toList $ Map.union jsAttrsStatic jsAttrsDynamic flip unHandlerFor hd $ do render <- getUrlRenderParams @@ -564,7 +581,7 @@ widgetToPageContent w = HandlerFor $ \hd -> do ^{mkScriptTag s} $maybe j <- jscript $maybe s <- jsLoc -