-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Dynamic links - replaceLink function
This feature enables the creation of dynamic links in the template document. The hyperlink URLs are stored in the `.rels` files, so the most direct approach was to create a new `replaceLink` function using the `replaceImage` implementation as "inspiration".
- Loading branch information
Showing
10 changed files
with
87 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Dynamic Links | ||
|
||
You can replace hyperlinks in the template file with dynamic links by using the `replaceLink` function after a placeholder link in the document: | ||
|
||
<code> | ||
{<i>%=replaceLink(url)%</i>} | ||
</code> | ||
|
||
The value of `url` is not validated, it is converted to string if needed. | ||
|
||
The expression replaces the link URL in the hyperlink preceding this expression, therefore, it should be placed immediately after the link, we want to modify. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Replace links in template | ||
|
||
In this example, you can see how to replace hyperlinks in a `for` loop in the template document. | ||
The `urls` array in the input JSON map contains the URLs generated into the result. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"urls": [ | ||
"https://stencil.erdos.dev", | ||
"https://httpbin.org/get?data=1&data2=2" | ||
] | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
(ns stencil.postprocess.links | ||
(:require [clojure.zip :as zip] | ||
[stencil.functions :refer [call-fn]] | ||
[stencil.log :as log] | ||
[stencil.ooxml :as ooxml] | ||
[stencil.model.relations :as relations] | ||
[stencil.types :refer [ControlMarker]] | ||
[stencil.util :refer [fail find-first iterations dfs-walk-xml-node]])) | ||
|
||
(set! *warn-on-reflection* true) | ||
|
||
;; Tells if the reference of an adjacent hyperlink node should be replaced in postprocess step. | ||
(defrecord ReplaceLink [relation] ControlMarker) | ||
|
||
(defn- update-link [link-node, ^ReplaceLink data] | ||
(assert (= ooxml/hyperlink (:tag link-node))) | ||
(assert (instance? ReplaceLink data)) | ||
(let [current-rel (-> link-node :attrs ooxml/r-id) | ||
new-val (-> data .relation)] | ||
(assert new-val) | ||
(log/debug "Replacing hyperlink relation {} by {}" current-rel new-val) | ||
(assoc-in link-node [:attrs ooxml/r-id] new-val))) | ||
|
||
(defn- replace-link [marker-loc] | ||
(if-let [link-loc (->> (zip/remove marker-loc) | ||
(iterations zip/prev) | ||
(find-first (comp #{ooxml/hyperlink} :tag zip/node)))] | ||
(zip/edit link-loc update-link (zip/node marker-loc)) | ||
(fail "Did not find hyperlink to replace. The location of target link must precede the replaceLink() function call location." {}))) | ||
|
||
(defn replace-links [xml-tree] | ||
(dfs-walk-xml-node | ||
xml-tree | ||
(partial instance? ReplaceLink) | ||
replace-link)) | ||
|
||
;; This duplicates both stencil.postprocess.image/->relation-id, | ||
;; and stencil.model.relations/->relation-id | ||
;; TODO: maybe make stencil.model.relations/->relation-id public | ||
(defn- ->relation-id [] (str (gensym "srel"))) | ||
|
||
(defn- link-url->relation [url] | ||
(let [new-rel (->relation-id)] | ||
{:new-id new-rel | ||
:stencil.model/type relations/rel-type-hyperlink | ||
:stencil.model/target url | ||
:stencil.model/mode "External"})) | ||
|
||
;; replaces the nearest link's URK with the parameter value | ||
(defmethod call-fn "replaceLink" [_ url] | ||
(let [new-relation (link-url->relation (str url))] | ||
(relations/add-extra-file! new-relation) | ||
(->ReplaceLink (:new-id new-relation)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters