Skip to content

Commit f56982e

Browse files
authored
Merge pull request #469 from line-o/improve-caching-master
fix: improve caching for all rendered pages
2 parents 5cddd08 + c3e2ce1 commit f56982e

File tree

9 files changed

+338
-351
lines changed

9 files changed

+338
-351
lines changed

controller.xql

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,17 @@ declare function local:serve-not-found-page() as element() {
4444
declare variable $local:view-module-url := $exist:controller || "/modules/view.xql";
4545
declare function local:render-page($page-template as xs:string, $parameters as map(*)) as element() {
4646
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
47-
<forward url="{$exist:controller}/pages/{$page-template}"/>
47+
<forward url="{$exist:controller}/pages/{$page-template}" method="get" />
4848
<view>
49-
<forward url="{$local:view-module-url}">{
49+
<forward url="{$local:view-module-url}">
50+
{
5051
map:for-each($parameters, function ($name as xs:string, $value as xs:string) as element() {
5152
<add-parameter xmlns="http://exist.sourceforge.net/NS/exist"
5253
name="{$name}" value="{$value}" />
5354
})
54-
}</forward>
55+
}
56+
<add-parameter name="x-method" value="{lower-case(request:get-method())}" />
57+
</forward>
5558
</view>
5659
<error-handler>
5760
<forward url="{$exist:controller}/pages/error-page.xml" method="get"/>

expath-pkg.xml.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://expath.org/ns/pkg" name="@url@" abbrev="@name@" version="@version@" spec="1.0">
33
<title>@title@</title>
44
<dependency processor="http://exist-db.org" semver-min="6.2.0"/>
5-
<dependency package="http://exist-db.org/html-templating" />
5+
<dependency package="http://exist-db.org/html-templating" semver-min="1.1.0" />
66
<dependency package="http://expath.org/ns/crypto" version="6.0.1"/>
77
<dependency package="http://www.functx.com"/>
88
<dependency package="http://existsolutions.com/apps/tei-publisher-lib" version="2.10.1"/>

modules/app.xqm

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,60 @@ function app:handle-error($node as node(), $model as map(*), $code as xs:integer
158158
()
159159
};
160160

161+
(: For the purpose of comparing the resource's last modified date with the If-Modified-Since
162+
: header supplied by the client, we must truncate any milliseconds from the last modified date.
163+
: This is because HTTP-date is only specific to the second.
164+
: @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 :)
165+
declare function app:modified-since ($last-modified as xs:dateTime?, $if-modified-since as xs:dateTime?) as xs:boolean {
166+
util:log("info", ('---pages:modified-since----', $last-modified, '<>', $if-modified-since)),
167+
exists($last-modified) and
168+
exists($if-modified-since) and
169+
$last-modified - $if-modified-since < xs:dayTimeDuration("PT1S")
170+
};
171+
172+
declare function app:safe-parse-if-modified-since-header() as xs:dateTime? {
173+
try {
174+
parse-ietf-date(
175+
request:get-attribute("if-modified-since"))
176+
} catch err:FORG0010 { () }
177+
};
178+
179+
declare function app:last-modified($publication-config as map(*), $document-id as xs:string?, $section-id as xs:string?) {
180+
if ($document-id and $section-id and map:contains($publication-config, "section-last-modified")) then (
181+
$publication-config?section-last-modified($document-id, $section-id)
182+
) else if ($document-id and map:contains($publication-config, "document-last-modified")) then (
183+
$publication-config?document-last-modified($document-id)
184+
) else if (map:contains($publication-config, "publication-last-modified")) then (
185+
$publication-config?publication-last-modified()
186+
) else ()
187+
};
188+
189+
declare function app:created($publication-config as map(*), $document-id as xs:string?, $section-id as xs:string?) {
190+
if ($section-id and $document-id and map:contains($publication-config, "section-created")) then (
191+
$publication-config?section-created($document-id, $section-id)
192+
) else if ($document-id and map:contains($publication-config, "document-created")) then (
193+
$publication-config?document-created($document-id)
194+
) else ()
195+
};
196+
197+
161198
declare function app:format-http-date($dateTime as xs:dateTime) as xs:string {
162199
$dateTime
163200
=> adjust-dateTime-to-timezone(xs:dayTimeDuration("PT0H"))
164201
=> format-dateTime("[FNn,*-3], [D01] [MNn,*-3] [Y0001] [H01]:[m01]:[s01] [Z0000]", "en", (), ())
165202
};
166203

167-
declare function app:set-last-modified($last-modified as xs:dateTime) {
168-
response:set-header("Last-Modified", app:format-http-date($last-modified))
204+
declare function app:set-last-modified($last-modified as xs:dateTime?) as empty-sequence() {
205+
if (empty($last-modified)) then () else (
206+
response:set-header("Last-Modified", app:format-http-date($last-modified)),
207+
response:set-header("Cache-Control", "max-age: 300; must-revalidate")
208+
)
169209
};
170210

171-
declare function app:set-created($created as xs:dateTime) {
172-
response:set-header("Created", app:format-http-date($created))
211+
declare function app:set-created($created as xs:dateTime?) as empty-sequence() {
212+
if (empty($created)) then () else (
213+
response:set-header("Created", app:format-http-date($created))
214+
)
173215
};
174216

175217
(:
@@ -556,7 +598,9 @@ declare function app:insert-url-parameter($node as node(), $model as map(*)) {
556598
};
557599

558600
declare function app:error-description($node as node(), $model as map(*)) {
559-
try {templates:error-description($node, $model)}
601+
try {
602+
templates:error-description($node, $model)
603+
}
560604
catch * {
561605
element { node-name($node) } {
562606
$node/@*,

modules/config.xqm

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -772,56 +772,55 @@ declare variable $config:PUBLICATION-COLLECTIONS :=
772772
};
773773

774774
declare variable $config:OPEN_GRAPH_KEYS := ("og:type", "twitter:card", "twitter:site", "og:site_name", "og:title", "og:description", "og:image", "og:url", "citation");
775-
775+
776776
declare variable $config:OPEN_GRAPH as map(xs:string, function(*)) := map{
777-
"twitter:card" : function($node, $model) {
777+
"twitter:card": function($node, $model) {
778778
<meta property='twitter:card' content='summary'/>
779779
},
780-
"twitter:site" : function($node, $model) {
780+
"twitter:site": function($node, $model) {
781781
<meta property='twitter:site' content='@HistoryAtState'/>
782782
},
783-
"og:site_name" : function($node, $model) {
783+
"og:site_name": function($node, $model) {
784784
<meta property='og:site_name' content='Office of the Historian'/>
785785
},
786-
"og:image" : function($node, $model) {
787-
786+
"og:image": function($node, $model) {
788787
for $img in $model?data//tei:graphic
789788
return
790789
<meta property="og:image" content="https://static.history.state.gov/{$model?base-path}/{$img/@url}"/>,
791790
<meta property="og:image" content="https://static.history.state.gov/images/avatar_big.jpg"/>,
792791
<meta property="og:image:width" content="400"/>,
793792
<meta property="og:image:height" content="400"/>,
794793
<meta property="og:image:alt" content="Office of the Historian social media avatar"/>
795-
796794
},
797-
"og:type" : function($node, $model) {
795+
"og:type": function($node, $model) {
798796
<meta property="og:type" content="{
799797
let $publication-id := $model?publication-id
800-
let $pub.type := $config:PUBLICATIONS?($publication-id)?open-graph?("og:type")
798+
let $pub-type := $config:PUBLICATIONS?($publication-id)?open-graph?("og:type")
801799
return
802-
($pub.type!.($node, $model), 'website')[1]
800+
($pub-type ! .($node, $model), 'website')[1]
803801
}"/>
804802
},
805-
"og:title" : function($node, $model) {
803+
"og:title": function($node, $model) {
806804
<meta property="og:title" content="{pages:generate-short-title($node, $model)}"/>
807805
},
808-
"og:description" : function($node, $model) {
806+
"og:description": function($node, $model) {
809807
<meta property="og:description" content="Office of the Historian"/>
810808
},
811-
"og:url" : function($node, $model) {
809+
"og:url": function($node, $model) {
812810
<meta property="og:url" content="{$model?url}"/>
813811
},
814-
"citation" : function ($node, $model) {
815-
let $cls as array(*) :=
816-
let $citation-meta as function(*)? := $config:PUBLICATIONS?($model?publication-id)?citation-meta
817-
return if (exists($model?citation-meta)) then
818-
array { $model?citation-meta }
812+
"citation": function ($node, $model) as element(meta)* {
813+
let $citation-meta as function(*)? := $config:PUBLICATIONS?($model?publication-id)?citation-meta
814+
let $cls as array(*) := array {
815+
if (exists($model?citation-meta)) then
816+
$model?citation-meta
819817
else if (exists($citation-meta)) then
820-
array { $citation-meta($node, $model) }
818+
$citation-meta($node, $model)
821819
else
822-
array { config:default-citation-meta($node, $model) }
823-
let $metas as element(meta)* := config:cls-to-html($cls)
824-
return $metas
820+
config:default-citation-meta($node, $model)
821+
}
822+
823+
return config:cls-to-html($cls)
825824
}
826825
};
827826

@@ -1044,19 +1043,24 @@ declare function config:tei-document-citation-meta($node as node()?, $model as m
10441043

10451044
declare function config:tei-shared-citation-meta($node as node()?, $model as map(*)?, $doc as document-node()?) as map(*) {
10461045
let $doc := $config:PUBLICATIONS?($model?publication-id)?select-document($model?document-id)
1047-
let $editors :=
1048-
for $editor in $doc/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:editor[@role eq 'primary']
1046+
1047+
let $fileDesc := $doc/tei:TEI/tei:teiHeader/tei:fileDesc
1048+
let $editors :=
1049+
for $editor in $fileDesc/tei:titleStmt/tei:editor[@role eq 'primary']
10491050
let $name-parts := tokenize($editor, '\s')
10501051
return map{
1051-
'family': $name-parts[last()],
1052-
'given': string-join($name-parts[position() ne last()], ' ')
1052+
'family': $name-parts[last()],
1053+
'given': string-join($name-parts[position() ne last()], ' ')
10531054
}
1054-
let $series_title := $doc/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title[@type='series']/string(.)
1055-
let $series_number := $doc/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title[@type='sub-series']/string(.)
1056-
let $volume := $doc/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title[@type='volume-number']/string(.)
1057-
let $publisher := $doc/tei:TEI/tei:teiHeader/tei:fileDesc/tei:publicationStmt/tei:publisher/string(.)
1058-
let $issued := $doc/tei:TEI/tei:teiHeader/tei:fileDesc/tei:publicationStmt/tei:date[@type eq 'publication-date']/string(.)
1059-
let $isbn := $doc/tei:TEI/tei:teiHeader/tei:fileDesc/tei:publicationStmt/tei:idno[@type eq 'isbn-13']/string(.)
1055+
1056+
let $series_title := $fileDesc/tei:titleStmt/tei:title[@type='series']/string()
1057+
let $series_number := $fileDesc/tei:titleStmt/tei:title[@type='sub-series']/string()
1058+
let $volume := $fileDesc/tei:titleStmt/tei:title[@type='volume-number']/string()
1059+
1060+
let $publisher := $fileDesc/tei:publicationStmt/tei:publisher/string()
1061+
let $issued := $fileDesc/tei:publicationStmt/tei:date[@type eq 'publication-date']/string()
1062+
let $isbn := $fileDesc/tei:publicationStmt/tei:idno[@type eq 'isbn-13']/string()
1063+
10601064
return map:merge((
10611065
config:default-citation-meta($node, $model),
10621066
if (exists($editors)) then map{'editor': array { $editors }} else (),
@@ -1109,7 +1113,7 @@ declare %templates:wrap function config:csl-json($node as node(), $model as map(
11091113
serialize(array { config:default-citation-meta($node, $model) }, map{'method':'json'}) => normalize-space()
11101114
};
11111115

1112-
declare variable $config:cls-to-zotero as map(xs:string, function(*)) := map {
1116+
declare variable $config:cls-to-zotero as map(xs:string, function(*)) := map {
11131117
"ISBN":
11141118
function($value) as element(meta)*{
11151119
<meta name="citation_isbn" content="{$value}"/>
@@ -1225,9 +1229,9 @@ declare function config:cls-name($name as map(*)) {
12251229
declare function config:cls-date($date as map(*)) {
12261230
if ($date?raw castable as xs:date or matches($date?raw, '\d{4}(-\d{2}(-\d{2})?)?')) then
12271231
$date?raw
1228-
else if ($date?date-parts!array:size(.) eq 1) then
1232+
else if (array:size($date?date-parts) eq 1) then
12291233
config:cls-date-parts($date?date-parts?1)
1230-
else ()
1234+
else ()
12311235
};
12321236

12331237
declare function config:cls-date-parts($date as array(*)) {
@@ -1239,9 +1243,9 @@ declare function config:cls-date-parts($date as array(*)) {
12391243
};
12401244

12411245
declare function config:cls-to-html($json as array(map(*))) as element(meta)* {
1242-
let $citation := $json?1
1243-
for $key in map:keys($citation)
1244-
let $value := $citation?($key)
1245-
let $lookup as function(*)? := $config:cls-to-zotero?($key)
1246-
return if (exists($lookup)) then $lookup($value) else ()
1246+
map:for-each($json?1, function ($key, $value) {
1247+
if (map:contains($config:cls-to-zotero, $key)) then
1248+
$config:cls-to-zotero?($key)($value)
1249+
else ()
1250+
})
12471251
};

0 commit comments

Comments
 (0)