forked from abaevdict/abaev-basex
transition to htmx, made truly infinite scroll
This commit is contained in:
parent
a65037f8ea
commit
cd513bd796
26 changed files with 849 additions and 1253 deletions
|
@ -1,96 +0,0 @@
|
|||
module namespace dict = 'http://ossetic-studies.org/ns/abaevdict-site/dictionary';
|
||||
|
||||
import module namespace shared = 'http://ossetic-studies.org/ns/abaevdict-site/shared' at '../shared/shared.xq';
|
||||
import module namespace abv-m = 'http://ossetic-studies.org/ns/abaevdict-mod' at '../../abv-mod.xqm';
|
||||
|
||||
(: Sidebar with entry list. Requires abaev.js to be loaded. :)
|
||||
|
||||
declare function dict:sidebar($lang as xs:string) {
|
||||
(
|
||||
<button id="open-leftbar">
|
||||
{html:doc('../../../static/chevron-right.svg')}
|
||||
</button>,
|
||||
<button id="close-leftbar">
|
||||
{html:doc('../../../static/chevron-left.svg')}
|
||||
</button>,
|
||||
<aside id="leftbar">
|
||||
<fieldset>
|
||||
<input type="text" id="filter-entries"
|
||||
placeholder="{if ($lang = 'ru') then 'Быстрый фильтр' else 'Quick filter…'}"/>
|
||||
<label>
|
||||
<input id="show-re" type="checkbox" role="switch"></input>
|
||||
{if ($lang = 'ru') then 'Производные' else 'Show subentries'}
|
||||
</label>
|
||||
</fieldset>
|
||||
<nav id="entrylist"></nav> <!-- To be filled dynamically in js -->
|
||||
</aside>
|
||||
)
|
||||
};
|
||||
|
||||
declare function dict:main-view($lang as xs:string,
|
||||
$p as xs:integer,
|
||||
$xpath as xs:string,
|
||||
$entry as xs:string) {
|
||||
(dict:sidebar($lang),
|
||||
<main>
|
||||
{for $doc at $i in $shared:sorted
|
||||
where $i > ($p - 1) * $shared:items-per-page and $i <= $p * $shared:items-per-page
|
||||
let $html := if ($xpath != '' and $entry = $doc/@xml:id)
|
||||
then abv-m:mark-element(
|
||||
doc(`abaevdict_{$lang}/xml/{$doc/@xml:id}.xml`),
|
||||
$xpath) => abv-m:make-html($lang)
|
||||
else
|
||||
let $sd := session:get('searchData')
|
||||
let $sn := session:get('searchN')
|
||||
return if (exists($sd) and $sd($sn)('entry') = $doc/@xml:id)
|
||||
then abv-m:make-html($sd($sn)('tei'), $lang)
|
||||
else doc(`abaevdict_{$lang}/html/{$doc/@xml:id}.html`)
|
||||
return <div class="abv-lex">{(
|
||||
(: Block with icons to the left of entry (floating) :)
|
||||
<div class="icons">
|
||||
{
|
||||
<a href="dict/{$doc/@xml:id}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link-45deg" viewBox="0 0 16 16">
|
||||
<path d="M4.715 6.542 3.343 7.914a3 3 0 1 0 4.243 4.243l1.828-1.829A3 3 0 0 0 8.586 5.5L8 6.086a1 1 0 0 0-.154.199 2 2 0 0 1 .861 3.337L6.88 11.45a2 2 0 1 1-2.83-2.83l.793-.792a4 4 0 0 1-.128-1.287z"/>
|
||||
<path d="M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0 1 1 2.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 1 0-4.243-4.243z"/>
|
||||
</svg>
|
||||
</a>,
|
||||
if (doc('abaevdict_index/mentioned_en.xml')/lang-index
|
||||
/lang[@id != 'os' and
|
||||
not(starts-with(@id,'os-'))]/word/entry[@id=string($doc/@xml:id)])
|
||||
then <a class="abv-map" data-abv-entry="{$doc/@xml:id}">
|
||||
<img src="/static/map.png"></img>
|
||||
</a>}</div>,
|
||||
$html)}</div>
|
||||
}
|
||||
</main>,
|
||||
<footer>
|
||||
<nav class="pagination">
|
||||
<ul>
|
||||
<li>
|
||||
{if ($p > 1) then <a href="?page={$p - 1}">Previous page</a> else ()}
|
||||
</li>
|
||||
</ul>
|
||||
<!-- <ul><li>Page {$p} of {$page:total}</li></ul> -->
|
||||
<ul class="abv-nextpage">
|
||||
<li>
|
||||
{if ($p < $shared:total) then
|
||||
<a class="pagination__next" href="?page={$p + 1}">Next page</a> else ()}
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</footer>,
|
||||
<dialog id="modal_map">
|
||||
<article>
|
||||
<header>
|
||||
<button class="abv-close-map" aria-label="Close" rel="prev">
|
||||
</button>
|
||||
<p>{if ($lang = 'ru') then 'Карта' else 'Map'}</p>
|
||||
</header>
|
||||
<p>
|
||||
<div id="map_display" style="width:100%;height:80%;"></div>
|
||||
</p>
|
||||
<footer><button class="abv-close-map">{if ($lang = 'ru') then 'Закрыть' else 'Close'}</button></footer>
|
||||
</article>
|
||||
</dialog>)
|
||||
};
|
182
xq/site/components/entries.xqm
Normal file
182
xq/site/components/entries.xqm
Normal file
|
@ -0,0 +1,182 @@
|
|||
module namespace entries = 'http://ossetic-studies.org/ns/abaevdict-site/entries';
|
||||
|
||||
declare namespace tei = "http://www.tei-c.org/ns/1.0";
|
||||
|
||||
import module namespace abv-m = 'http://ossetic-studies.org/ns/abaevdict-mod' at '../../abv-mod.xqm';
|
||||
|
||||
(: MAIN DICTIONARY VIEW COMPONENT :)
|
||||
|
||||
(: GET INDIVIDUAL ENTRY :)
|
||||
|
||||
declare %rest:path("{$lang}/entries/{$id}")
|
||||
%rest:query-param("query", "{$query}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function entries:entry($lang as xs:string, $id as xs:string, $query as xs:string?) {
|
||||
if (count($query) = 0) then
|
||||
doc(`abaevdict_{$lang}/html/{$id}.html`)
|
||||
else
|
||||
let $xml := doc(`abaevdict_{$lang}/xml/{$id}.xml`)
|
||||
let $marked := ft:mark(
|
||||
xquery:eval(
|
||||
`declare namespace tei = "http://www.tei-c.org/ns/1.0";
|
||||
declare namespace abv = "http://ossetic-studies.org/ns/abaevdict";
|
||||
.[{$query}]`, {'': $xml})
|
||||
)
|
||||
return abv-m:make-html($marked,$lang)
|
||||
};
|
||||
|
||||
declare %rest:path("/entries/{$id}")
|
||||
%rest:query-param("query", "{$query}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function entries:entry($id as xs:string, $query as xs:string?) {
|
||||
entries:entry('en', $id, $query)
|
||||
};
|
||||
|
||||
(: GET ENTRIES CATALOG :)
|
||||
|
||||
declare %rest:path("{$lang}/entries")
|
||||
%rest:query-param("per-chunk", "{$per-chunk}", 5)
|
||||
%rest:query-param("query", "{$query}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function entries:entries($lang as xs:string,
|
||||
$per-chunk as xs:integer,
|
||||
$query as xs:string?) {
|
||||
let $docs := abv-m:collection($lang,'xml')/tei:entry
|
||||
let $chosen := if($query) then
|
||||
xquery:eval(`declare namespace tei = "http://www.tei-c.org/ns/1.0";
|
||||
declare namespace abv = "http://ossetic-studies.org/ns/abaevdict";
|
||||
.[{$query}]`,
|
||||
{'': $docs})/string(@xml:id)
|
||||
for tumbling window $w in abv-m:lookups()
|
||||
start at $s when true()
|
||||
only end at $e when $e - $s eq ($per-chunk - 1)
|
||||
return
|
||||
<div class="abv-chunk">
|
||||
{
|
||||
for $entry in $w
|
||||
let $id := $entry/@xml:id
|
||||
return
|
||||
<div class="abv-lex"
|
||||
hx-get="/{$lang}/entries/{$id}"
|
||||
hx-target="find article"
|
||||
hx-trigger="intersect once from:closest .abv-chunk"
|
||||
hx-swap="outerHTML focus-scroll:true">
|
||||
{if ($id = $chosen) then
|
||||
attribute hx-vals {
|
||||
`{'{'}"query": "{$query}"{'}'}`
|
||||
}}
|
||||
{
|
||||
<article id="{$id}"
|
||||
class="abv-entry">
|
||||
</article>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
};
|
||||
|
||||
declare %rest:path("/entries")
|
||||
%rest:query-param("per-chunk", "{$per-chunk}", 5)
|
||||
%rest:query-param("query", "{$query}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function entries:entries($per-chunk as xs:integer,
|
||||
$query as xs:string?) {
|
||||
entries:entries('en', $per-chunk, $query)
|
||||
};
|
||||
|
||||
(: LIST OF ENTRIES FOR MENU :)
|
||||
|
||||
declare %rest:path("{$lang}/entrylist")
|
||||
%rest:query-param("filter", "{$filter}")
|
||||
%rest:query-param("subentries", "{$subentries}", false())
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function entries:entrylist($lang as xs:string,
|
||||
$filter as xs:string?,
|
||||
$subentries as xs:boolean?) {
|
||||
<nav id="entrylist">
|
||||
<ul>
|
||||
{for $e in abv-m:lookups($subentries)
|
||||
let $txt := $e/text()
|
||||
return
|
||||
if ($txt contains text {`{$filter}.*`} using wildcards at start) then
|
||||
<li>
|
||||
{
|
||||
if (name($e) = 're') then
|
||||
attribute class {'abv-menu-re'} else (),
|
||||
<a href="#{$e/@xml:id}">
|
||||
{$e/text()}
|
||||
</a>
|
||||
}
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</nav>
|
||||
};
|
||||
|
||||
declare %rest:path("entrylist")
|
||||
%rest:query-param("filter", "{$filter}")
|
||||
%rest:query-param("subentries", "{$subentries}", false())
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function entries:entrylist($filter as xs:string?,
|
||||
$subentries as xs:boolean?) {
|
||||
entries:entrylist('en',$filter,$subentries)
|
||||
};
|
||||
|
||||
(: QUICK ENTRY LIST SIDEBAR :)
|
||||
|
||||
declare function entries:sidebar($lang as xs:string) {
|
||||
(<button id="close-leftbar"
|
||||
hx-on-click="document.getElementById('leftbar').style.display = 'none';
|
||||
document.getElementById('open-leftbar').style.display = 'block';
|
||||
document.getElementById('close-leftbar').style.display = 'none'">
|
||||
{html:doc('../../../static/chevron-left.svg')}
|
||||
</button>,
|
||||
<button id="open-leftbar"
|
||||
hx-on-click="document.getElementById('leftbar').style.display = 'block';
|
||||
document.getElementById('open-leftbar').style.display = 'none';
|
||||
document.getElementById('close-leftbar').style.display = 'block'">
|
||||
{html:doc('../../../static/chevron-right.svg')}
|
||||
</button>,
|
||||
<aside id="leftbar">
|
||||
<fieldset>
|
||||
<input type="text" id="filter-entries" name="filter"
|
||||
hx-get="./entrylist" hx-target="#entrylist"
|
||||
hx-swap="outerHTML"
|
||||
hx-trigger="input changed"
|
||||
placeholder="{if ($lang = 'ru') then 'Быстрый фильтр' else 'Quick filter…'}"/>
|
||||
<label>
|
||||
<input id="show-re"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
name="subentries" value="1"
|
||||
hx-get="./entrylist" hx-target="#entrylist"
|
||||
hx-trigger="change"
|
||||
hx-swap="outerHTML"/>
|
||||
{if ($lang = 'ru') then 'Производные' else 'Show subentries'}
|
||||
</label>
|
||||
</fieldset>
|
||||
<nav id="entrylist"
|
||||
hx-get="./entrylist"
|
||||
hx-swap="outerHTML"
|
||||
hx-trigger="load">
|
||||
</nav>
|
||||
</aside>)
|
||||
};
|
|
@ -1,49 +0,0 @@
|
|||
module namespace index = 'http://ossetic-studies.org/ns/abaevdict-site/index';
|
||||
|
||||
import module namespace shared = 'http://ossetic-studies.org/ns/abaevdict-site/shared' at '../shared/shared.xq';
|
||||
|
||||
declare function index:content($lang as xs:string) {
|
||||
let $mlangs := doc(`abaevdict_index/langnames.xml`)/csv[1]/record
|
||||
return
|
||||
<html>
|
||||
{shared:head('HEDO – Index', <script src="/static/abaev-index.js"></script>)}
|
||||
<body>
|
||||
{shared:header($lang, `../{shared:invert-lang($lang)}/index`)}
|
||||
<main>
|
||||
<div class="index">
|
||||
<div class="langs">
|
||||
<label>{if ($lang = 'ru') then 'Языки' else 'Languages'}</label>
|
||||
<select id="abv-select-lang" size="99999">
|
||||
{
|
||||
for $mlang in $mlangs
|
||||
let $mlang-id := $mlang/code/text()
|
||||
let $mlang-name := if ($lang = 'ru') then $mlang/ru/text() else $mlang/en/text()
|
||||
where $mlang-name != ''
|
||||
order by $mlang-name
|
||||
return
|
||||
<option value="{$mlang-id}">
|
||||
{
|
||||
$mlang-name
|
||||
}
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="forms">
|
||||
<Label>{if ($lang = 'ru') then 'Формы' else 'Forms'}</Label>
|
||||
<select id="abv-select-word" size="99999">
|
||||
</select>
|
||||
</div>
|
||||
<div class="entries">
|
||||
<Label>{if ($lang = 'ru') then 'Лексемы' else 'Lexemes'}</Label>
|
||||
<select id="abv-select-entry" size="99999">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="index-submit">
|
||||
<button id="btn-index-submit" hidden="1">{if ($lang = 'ru') then 'К форме' else 'Go to form'}</button>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
};
|
149
xq/site/components/index.xqm
Normal file
149
xq/site/components/index.xqm
Normal file
|
@ -0,0 +1,149 @@
|
|||
module namespace index = 'http://ossetic-studies.org/ns/abaevdict-site/index';
|
||||
|
||||
declare namespace tei = "http://www.tei-c.org/ns/1.0";
|
||||
|
||||
import module namespace abv-m = 'http://ossetic-studies.org/ns/abaevdict-mod' at '../../abv-mod.xqm';
|
||||
|
||||
(: GET LANGUAGE LIST :)
|
||||
|
||||
declare %rest:path("{$lang}/index/languages")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function index:languages($lang as xs:string) {
|
||||
let $mlangs := doc(`abaevdict_index/langnames.xml`)/csv[1]/record
|
||||
for $mlang in $mlangs
|
||||
let $mlang-id := $mlang/code/text()
|
||||
let $mlang-name := if ($lang = 'ru') then $mlang/ru/text() else $mlang/en/text()
|
||||
where $mlang-name != ''
|
||||
order by $mlang-name
|
||||
return
|
||||
<option value="{$mlang-id}">
|
||||
{
|
||||
$mlang-name
|
||||
}
|
||||
</option>
|
||||
};
|
||||
|
||||
declare %rest:path("/index/languages")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function index:languages() {
|
||||
index:languages('en')
|
||||
};
|
||||
|
||||
(: FORM LIST :)
|
||||
|
||||
declare %rest:path("{$lang}/index/forms")
|
||||
%rest:query-param("flang", "{$flang}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function index:forms($lang as xs:string, $flang as xs:string) {
|
||||
let $ments := doc(`abaevdict_index/mentioned_{$lang}.xml`)
|
||||
/lang-index[1]/lang[@id=$flang]/word
|
||||
for $w in $ments
|
||||
let $txt := string($w/@text)
|
||||
return <option value="{$txt}">{$txt}</option>
|
||||
};
|
||||
|
||||
declare %rest:path("index/forms")
|
||||
%rest:query-param("flang", "{$flang}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function index:forms($flang as xs:string) {
|
||||
index:forms('en',$flang)
|
||||
};
|
||||
(: RELATED ENTRY LIST :)
|
||||
|
||||
declare %rest:path("{$lang}/index/entries")
|
||||
%rest:query-param("flang", "{$flang}")
|
||||
%rest:query-param("word", "{$word}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function index:entries($lang as xs:string,
|
||||
$flang as xs:string,
|
||||
$word as xs:string) {
|
||||
let $entries := doc(`abaevdict_index/mentioned_{$lang}.xml`)
|
||||
/lang-index[1]/lang[@id=$flang]/word[@text=$word]/entry
|
||||
for $e in $entries
|
||||
let $id := $e/@id
|
||||
let $txt := abv-m:entry-form-by-id($id)
|
||||
let $query := `./@xml:id = '{$id}' and .//text() contains
|
||||
text '{$word}' using diacritics sensitive`
|
||||
return <tr>
|
||||
<td>{string-join(
|
||||
distinct-values($e/ref/gloss/string(@text)),', ')}</td>
|
||||
<td>
|
||||
<a href="./dictionary?query={$query}#{$id}">{$txt}</a>
|
||||
</td>
|
||||
<td>
|
||||
{
|
||||
string-join(data(doc(`abaevdict_{$lang}/xml/{$id}.xml`)
|
||||
/tei:entry[1]/tei:sense/(tei:sense|tei:sense/tei:sense|.)
|
||||
/tei:cit/tei:quote),', ')
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
};
|
||||
|
||||
declare %rest:path("index/entries")
|
||||
%rest:query-param("flang", "{$flang}")
|
||||
%rest:query-param("word", "{$word}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function index:entries($flang as xs:string,
|
||||
$word as xs:string) {
|
||||
index:entries('en',$flang,$word)
|
||||
};
|
||||
|
||||
(: THE MAIN INDEX VIEW :)
|
||||
|
||||
declare function index:content($lang as xs:string) {
|
||||
<html>
|
||||
<body>
|
||||
<main>
|
||||
<div class="index">
|
||||
<div class="langs">
|
||||
<label>{if ($lang = 'ru') then 'Языки' else 'Languages'}</label>
|
||||
<select id="abv-select-lang" size="99999" name="flang"
|
||||
hx-get='./index/forms' hx-target="#abv-select-word" hx-trigger="input">
|
||||
{index:languages($lang)}
|
||||
</select>
|
||||
</div>
|
||||
<div class="forms">
|
||||
<label>{if ($lang = 'ru') then 'Формы' else 'Forms'}</label>
|
||||
<select id="abv-select-word" size="99999" name="word"
|
||||
hx-get="./index/entries" hx-target="#abv-select-entry" hx-trigger="input"
|
||||
hx-include="#abv-select-lang">
|
||||
</select>
|
||||
</div>
|
||||
<div class="entries">
|
||||
<label>{if ($lang = 'ru') then 'Лексемы' else 'Lexemes'}</label>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{if ($lang = 'ru') then 'Глоссы' else 'Gloss'}</th>
|
||||
<th scope="col">{if ($lang = 'ru') then 'Лексема' else 'Lemma'}</th>
|
||||
<th scope="col">{if ($lang = 'ru') then 'Перевод' else 'Translation'}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="abv-select-entry">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
};
|
61
xq/site/components/map.xqm
Normal file
61
xq/site/components/map.xqm
Normal file
|
@ -0,0 +1,61 @@
|
|||
module namespace map = 'http://ossetic-studies.org/ns/abaevdict-site/map';
|
||||
|
||||
import module namespace abv-m = 'http://ossetic-studies.org/ns/abaevdict-mod' at '../../abv-mod.xqm';
|
||||
|
||||
declare %rest:path("{$lang}/map")
|
||||
%rest:query-param("entry", "{$entry}")
|
||||
%rest:GET
|
||||
%rest:produces("text/html")
|
||||
%output:method("html")
|
||||
%output:html-version('5')
|
||||
function map:map($lang as xs:string, $entry as xs:string) {
|
||||
let $mapdata := abv-m:make-geomap(
|
||||
doc(`abaevdict_{$lang}/xml/{$entry}.xml`),
|
||||
$lang)
|
||||
return
|
||||
(<article>
|
||||
<header>
|
||||
<button class="abv-close-map" aria-label="Close" rel="prev">
|
||||
</button>
|
||||
<p>{if ($lang = 'ru') then 'Карта' else 'Map'}</p>
|
||||
</header>
|
||||
<p>
|
||||
<div id="map-display" style="width:100%;height:80%;"></div>
|
||||
</p>
|
||||
<footer>
|
||||
<button class="abv-close-map"
|
||||
hx-on-click="document.getElementById('modal_map').close()">
|
||||
{if ($lang = 'ru') then 'Закрыть' else 'Close'}
|
||||
</button>
|
||||
</footer>
|
||||
</article>,
|
||||
<script defer="1">
|
||||
{concat(`var mapdata = {json:serialize($mapdata)}`,
|
||||
"
|
||||
map = document.getElementById('map-display');
|
||||
var layout = {
|
||||
// title: {
|
||||
// text: 'Canadian cities',
|
||||
// font: {
|
||||
// family: 'Droid Serif, serif',
|
||||
// size: 16
|
||||
// }
|
||||
// },
|
||||
geo: {
|
||||
scope: 'world',
|
||||
resolution: 50,
|
||||
fitbounds: 'locations',
|
||||
showrivers: true,
|
||||
rivercolor: '#fff',
|
||||
showlakes: true,
|
||||
lakecolor: '#fff',
|
||||
showland: true,
|
||||
landcolor: '#EAEAAE',
|
||||
showcountries: false,
|
||||
subunitcolor: '#d3d3d3'
|
||||
}
|
||||
};
|
||||
Plotly.newPlot(map, [mapdata], layout);
|
||||
")}
|
||||
</script>)
|
||||
};
|
|
@ -1,31 +0,0 @@
|
|||
module namespace search = 'http://ossetic-studies.org/ns/abaevdict-site/search-modal';
|
||||
|
||||
import module namespace abv-m = 'http://ossetic-studies.org/ns/abaevdict-mod' at '../../abv-mod.xqm';
|
||||
|
||||
(: Modal that appears on all pages, with search results :)
|
||||
declare function search:content($lang as xs:string) {
|
||||
if (exists(session:get('searchData'))) then
|
||||
<dialog id="modal_searchResults">
|
||||
<article>
|
||||
<header>
|
||||
<button class="abv-close-search" aria-label="Close" rel="prev"/>
|
||||
<p>{if ($lang = 'ru') then 'Результаты поиска'
|
||||
else 'Search results'}</p>
|
||||
</header>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{if ($lang = 'ru') then '№' else 'No.'}</td>
|
||||
<td>{if ($lang = 'ru') then 'Лемма' else 'Lemma'}</td>
|
||||
<td>{if ($lang = 'ru') then 'Фрагмент' else 'Fragment'}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<footer>
|
||||
<button class="abv-close-search">{if ($lang = 'ru') then 'Закрыть' else 'Close'}</button>
|
||||
</footer>
|
||||
</article>
|
||||
</dialog>
|
||||
};
|
133
xq/site/components/search.xqm
Normal file
133
xq/site/components/search.xqm
Normal file
|
@ -0,0 +1,133 @@
|
|||
module namespace search = 'http://ossetic-studies.org/ns/abaevdict-site/search';
|
||||
|
||||
declare namespace tei = "http://www.tei-c.org/ns/1.0";
|
||||
|
||||
import module namespace abv-m = 'http://ossetic-studies.org/ns/abaevdict-mod' at '../../abv-mod.xqm';
|
||||
|
||||
declare variable $search:types :=
|
||||
(
|
||||
{
|
||||
'query': ".//text() contains text {'$'}",
|
||||
'ru': 'Везде',
|
||||
'en': 'All'
|
||||
},
|
||||
{
|
||||
'query': ".//tei:form/tei:orth//text() contains text {'$'}",
|
||||
'ru': 'Формы',
|
||||
'en': 'Forms'
|
||||
},
|
||||
{
|
||||
'query': ".//tei:cit[@type='translationEquivalent']//text() contains text {'$'}",
|
||||
'ru': 'Значения',
|
||||
'en': 'Meanings'
|
||||
},
|
||||
{
|
||||
'query': ".//tei:cit[@type='example']/tei:quote//text() contains text {'$'}",
|
||||
'ru': 'Примеры',
|
||||
'en': 'Examples'
|
||||
},
|
||||
{
|
||||
'query': ".//tei:cit[@type='translation']//text() contains text {'$'}",
|
||||
'ru': 'Переводы',
|
||||
'en': 'Translations'
|
||||
},
|
||||
{
|
||||
'query': ".//tei:mentioned/(tei:m|tei:w|tei:phr|tei:s)/text() contains text {'$'}",
|
||||
'ru': 'Цит. формы',
|
||||
'en': 'Mentioned'
|
||||
},
|
||||
{
|
||||
'query': ".//tei:gloss//text() contains text {'$'}",
|
||||
'ru': 'Глоссы',
|
||||
'en': 'Glosses'
|
||||
},
|
||||
{
|
||||
'query': "./tei:etym[1]//text() contains text {'$'}",
|
||||
'ru': 'Этимологии',
|
||||
'en': 'Etymology'
|
||||
},
|
||||
{
|
||||
'query': "$",
|
||||
'ru': 'XQuery',
|
||||
'en': 'XQuery'
|
||||
}
|
||||
);
|
||||
|
||||
(: GET SEARCH RESULTS :)
|
||||
|
||||
declare function search:content($lang as xs:string,
|
||||
$pattern as xs:string? := (),
|
||||
$text as xs:string? := ()) {
|
||||
<form role="search" id="abv-search"
|
||||
hx-post=""
|
||||
hx-select="main"
|
||||
hx-target="main"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="true">
|
||||
<select name="pattern" required="1">
|
||||
{
|
||||
for $opt in $search:types
|
||||
return
|
||||
<option value="{$opt('query')}">
|
||||
{
|
||||
if ($pattern = $opt('query')) then
|
||||
attribute selected {'1'},
|
||||
if ($lang = 'ru') then $opt('ru')
|
||||
else $opt('en')
|
||||
}
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
<input name="text" required="1"
|
||||
placeholder="{if ($lang = 'ru') then 'Искать' else 'Search'}"
|
||||
value="{$text}"
|
||||
aria-label="Search">
|
||||
{if (exists(session:get('searchQuery'))) then
|
||||
attribute disabled {"1"} }
|
||||
</input>
|
||||
<input type="submit" value="Submit"/>
|
||||
</form>,
|
||||
<table hx-boost="true" id="abv-search-results">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{if ($lang = 'ru') then 'Лексема' else 'Lemma'}</th>
|
||||
<th scope="col">{if ($lang = 'ru') then 'Перевод' else 'Translation'}</th>
|
||||
<th scope="col">{if ($lang = 'ru') then 'Контекст' else 'Context'}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{if (exists($pattern) and exists($text)) then
|
||||
let $entries := abv-m:collection($lang,'xml')/tei:entry
|
||||
let $query := replace($pattern, "\$", $text)
|
||||
let $hits :=
|
||||
ft:mark(xquery:eval(`declare namespace tei = "http://www.tei-c.org/ns/1.0";
|
||||
declare namespace abv = "http://ossetic-studies.org/ns/abaevdict";
|
||||
.[{$query}]`, {'': $entries}))
|
||||
for $hit in $hits
|
||||
return
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/{$lang}/dictionary?query={$query}#{$hit/@xml:id}">
|
||||
{$hit/tei:form[1]/tei:orth[1]}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{
|
||||
string-join(
|
||||
data($hit/tei:sense
|
||||
/(tei:sense|tei:sense/tei:sense|.)/tei:cit/tei:quote),
|
||||
', '
|
||||
)
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
{
|
||||
if (count($hit//*[tei:mark]) > 0) then
|
||||
util:strip-namespaces(($hit//*[tei:mark])[1])/child::node()
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue