On my website (driven by eXist-db 4.4) I have a search page:
http://localhost:8081/exist/apps/deheresi/search
This contains a simple form that submits a search request like:
http://localhost:8081/exist/apps/deheresi/search?keyword=someword
The page is served up through templates in eXist-db which are triggered by controller.xqlreceiving the request:
else if (starts-with(lower-case($exist:path), "/search")) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/search.html"/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<add-parameter name="searchterm" value="{$exist:resource}"/>
<add-parameter name="pagetype" value="search"/>
</forward>
</view>
</dispatch>
In this context, I would assume that $exist:resource would contain the some string which includes ?keyword=somewordor something to that effect (so that I can further parse the request). But nothing is being output to the parameter. I have a feeling I'm not understanding exactly how to get the query string from an http request in the eXist controller.
Many thanks in advance for any advice.
Just after I posted this I discovered https://exist-db.org/exist/apps/fundocs/view.html?uri=http://exist-db.org/xquery/request where
request:get-parameter($name as xs:string, $default-value as item()*) as xs:string*
Does exactly as needed, like this:
else if (starts-with(lower-case($exist:path), "/search")) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/search.html"/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<add-parameter name="searchterm" value="{request:get-parameter("keyword","")}"/>
<add-parameter name="pagetype" value="search"/>
</forward>
</view>
</dispatch>
Related
This question already has an answer here:
How do I handle phone numbers with NextJS Links?
(1 answer)
Closed 10 months ago.
Currently I am using nextjs/Link for handling tlf number and email inside of a contacts section in my footer. I use href property to send the user to mailto or directly to google maps when they click on the respective link. I read that using next/link for this purpose is not a good practise. What should i be using instead?
here is a snippet of my code:
interface Props {
contact: ContactType;
}
function Contact({ contact }: Props) {
return (
<Link href={contact.href ?? ''}>
<a className="flex gap-x-5" target={contact.target ?? ''}>
{contact.icon ? (
<div className="relative w-5 h-5">
<Image width={15} height={15} src={contact.icon} />
</div>
) : null}
<p> {contact.name} </p>
</a>
</Link>
);
}
export default Contact;
If your links lead to an external resource then you can use regular <a> tag without Next.js <Link>, same with mail or phone links and etc. Basically Link is only needed if you want to have SPA internal navigation between your own routes (navigation that will not reload the page).
From my understanding NEXT should be automatically generating the routes based on my folder structure.
I am mapping over article posts on news/index.tsx page but the urls I get are localhost3000/article-one when I need localhost3000/news/article-one
Can anyone point out where I'm going wrong?
{page?.articles.map((post, i) => {
return (
<Link
key={i}
href={post?.slug.current!}
>
{post?.title!}
</Link>
)
})}
Folder structure:
- pages
- news
- index.tsx
- [slug].tsx
EDIT
Addiction info:
Slugs are being pulled from Sanity headless CMS.
Tutorials often show routing by prepending news/ to the slug but this in turn is prepending news/ to all slugs
You can handle the dynamic routes in Next js in few ways, one of those is with With URL Object:
{page?.articles.map((post, i) => {
return (
<Link
key={i}
href={{
pathname: '/news/[slug]',
query: { slug: post?.slug?.current },
}}
>
<a>
{post?.title!}
</a>
</Link>
)
})}
Additional disclaimer. You always must add the anchor <a>...</a> as a child of Link Component.
Documentation: https://nextjs.org/docs/api-reference/next/link#with-url-object
Turns out to be a really simple fix..
The nav links that were getting /news/news prepended to their slugs needed a / prepended before them
From what I understand you should change your code to have the correct href:
{page?.articles.map((post, i) => {
return (
<Link
key={i}
href={`/news${post?.slug.current!}`}
>
{post?.title!}
</Link>
)
})}
I've been trying to forward the file to HTML template but it's not working. Here is the code in file.xql
{
for $resource in collection('/db/apps/myapp/data')
let $doc := request:get-parameter("filename", ())
let $uri := document-uri( root( $resource ) )
return
{document-uri( root( $resource ) )}
};
and here is controller.xql
if ($exist:path eq '') then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<redirect url="{request:get-uri()}/"/>
</dispatch>
else if ($exist:path eq "/") then
(: forward root path to index.xql :)
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<redirect url="index.html"/>
</dispatch>
else if (ends-with($exist:resource, ".html")) then
(: the html page is run through view.xql to expand templates :)
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<view>
<forward url="{$exist:controller}/modules/view.xql"/>
</view>
<error-handler>
<forward url="{$exist:controller}/error-page.html" method="get"/>
<forward url="{$exist:controller}/modules/view.xql"/>
</error-handler>
</dispatch>
else if (contains($exist:path, "/data/")) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/templates/file.html"/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<add-parameter name="filename" value="{$exist:resource}.xml"/>
</forward>
</view>
</dispatch>
But it goes to URL "http://localhost:8080/db/apps/myapp/data/let001.xml"
and not to "http://localhost:8080/db/apps/myapp/templates/file.html"
Any ideas what is wrong in the code?
I am working with eXist-db 4.2.1 and Xquery 3.1 using the eXist's default installation of controller.xql and view.xq.
I have a document.html to which I pass any incoming url structured with /doc/some-requested-doc-id at the end to produce a dynamically-created page based on some-requested-doc-id.
So, the incoming url can be either http://localhost:8080/exist/apps/deheresi/doc/MS609-0001 or
http://localhost:8080/exist/apps/deheresi/doc/MS609-0001.xml
and they are treated the same...
In the file controller.xql I have a condition for matching this request, which identifies /doc/ and cleans up the expected some-requested-doc-id using a function which is passed to parameter name="currentdoc":
[...]
else if (starts-with($exist:path, "/doc/")) then
(: strip out any extensions and rename global variable as .xml:)
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/document.html">
<add-parameter name="currentdoc"
value="{concat(functx:substring-before-match($exist:resource,'[.]'),'.xml')}"/>
</forward>
<view>
<forward url="{$exist:controller}/modules/view.xql"/>
</view>
</dispatch>
[...]
The requested .html file is as follows, which itself calls other HTML templates and/or dynamically created content in XQuery:
<div data-template="templates:surround" data-template-with="templates/site_wrapper.html" data-template-at="content">
<div data-template="document:title-bar"/>
<div class="col-sm-12">
<div class="col-md-2 sidebar">
<div data-template="document:doc-sidebar-sub1"/>
<div data-template="document:doc-sidebar-sub2"/>
<div data-template="document:doc-sidebar-sub3"/>
<div data-template="document:doc-sidebar-sub4"/>
</div>
<div class="col-md-10 document-view">
<div data-template="document:doc-xsl-docview"/>
</div>
</div>
</div>
The 5 data-template="document:... calls depend on the same parameter provided by <add-parameter>, for example <div data-template="document:title-bar"/> calls:
declare function document:title-bar(
$node as node(),
$model as map(*),
$currentdoc as xs:string)
{
let $persid := person:person-name(data(doc(concat($globalvar:URIdata,$currentdoc))/tei:TEI/tei:text//tei:persName[#role="dep"]/#nymRef))
let $doctypeen := data(doc(concat($globalvar:URIdata,$currentdoc))/tei:TEI/tei:text//tei:div[#type="doc_type"]/#subtype)
let $x :=
<div class="col-md-12 document-title">
<h2><span class="en">{$doctypeen}: </span><span class="fr">{document:doc-type-french($doctypeen)} : </span>{$persid}</h2>
</div>
return $x
};
Even if I hard-code the parameter in the module controller.xql:
<add-parameter name="currentdoc" value="MS609-00001.xml"/>
I still get the same error, which doesn't happen if I hard code the parameter in the template call:
The actual cardinality for parameter 3 does not match the
cardinality declared in the function's signature:
document:title-bar($node as node(), $model as map,
$currentdoc as xs:string) item()*.
Expected cardinality: exactly one, got 0.
The 'expected cardinality' suggests that the parameter is not coming into the function?
EDIT:
If I change the order of parameters in the function above to
declare function document:title-bar(
$currentdoc as xs:string,
$node as node(),
$model as map(*))
I get a different error:
Supplied argument 2 of function:
document:title-bar($currentdoc as xs:string,
$node as node(), $model as map) item()* does not
match required type. Required type node(), got map. `
Many thanks in advance.
The <add-parameter> directive needs to be moved to the 2nd <forward> directive—so that modules/view.xql has access to the parameter. The corrected version of this fragment of your controller is:
else if (starts-with($exist:path, "/doc/")) then
(: strip out any extensions and rename global variable as .xml:)
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/document.html"/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<add-parameter name="currentdoc" value="{concat(functx:substring-before-match($exist:resource,'[.]'),'.xml')}"/>
</forward>
</view>
</dispatch>
The templating documentation also shows this - see the 2nd code sample under the "Set up" section here: https://exist-db.org/exist/apps/doc/templating#D3.35.
(There was a mistake in the answer you referenced - which I have now corrected. Apologies, and thanks for your thorough testing and well-articulated questions!)
I'm new to js, react and css so this is going to be very basic but it's not to me. I have these containers and I'm trying to put a text field inside one of them but I'm getting syntax error at Text. Does it have something to do with < > />? Thank you
<View style={styles.top}
/>
<MapView style={styles.map}
region ={{
latitude:lat,
longitude:long,
latitudeDelta: 0.1,
longitudeDelta: 0.1,
}}
>
</MapView>
<View style={styles.bottom} />
</View>
);
Indeed it does. You need to close your jsx View tag.
<View style= {styles.container}>
<View style={styles.top}>
<Text> Hi there</Text>
</View>
</View>
The render method can only render a single root node i.e you only define one parent root in render method.
You can define multiple child root under one parent.