I'm trying to import a JSON file on my Vite app, whose paths are dynamically generated. So the import path for this JSON includes variables.
I know it's possible to do it with require, but I'm working with Svelte, and I cant use requires.
You can use a dynamic import() statement for that. This will return a promise, which has to be awaited, though. E.g.
<script lang="ts">
import meta from './meta.json';
const filePromise = import(/* #vite-ignore */ `./${meta.file}.json`);
</script>
{#await filePromise then file}
{file.property}
{/await}
There are some limitations to dynamic imports in Vite so the application can be built properly. The #vite-ignore comment silences a warning output about these limitations.
User will upload EDUPUB/Zip file from UI. We want to implement a REST api extension module to take EDUPUB/Zip file and ingest into a MarkLogic database. Does MarkLogic API api support this? Any suggestions?
I implemented the code below for extracting and uploading a EDUPUB/Zip file
xquery version "1.0-ml";
declare namespace zip="xdmp:zip";
declare function local:epubupload ($filepath as xs:string)
{
let $get_document :=xdmp:document-get($filepath)
let $get_uri := fn:document-uri($get_document)
let $get_document_uri := fn:concat($get_uri, "/")
let $get_collection := fn:tokenize($get_uri, "\\")[last()]
let $epub_extract := xdmp:zip-manifest($get_document)
for $each_file in $epub_extract/zip:part/text()
let $document_data := xdmp:zip-get($get_document, $each_file)
let $full_document_uri := fn:concat($get_document_uri, $each_file)
return xdmp:document-insert($full_document_uri, $document_data, (), $get_collection)
};
local:epubupload("c:\data\sample.epub")
But for the REST api what is the parameter? And how to get whole file from user system?
If you are creating your own REST extension, then you can use the following pattern on the zip payload:
1 Iterate over the zip file using xdmp:zip-manifest
2 For each entry, use xdmp:zip-get to extract the file
3 Save it into MarkLogic via xdmp:document-insert
Depending on how you posted the content, xdmp:base64-decode may be part of your code to actually get to your zip file.
I have been tinkering with this trigger for hours now, think I pinpointed the issue now.
I have set up an example trigger like in ML8 documentation.
Now I have modified it to a more real-world action.
The issue seems to be that I use a library module that hold my own functions in a lib.xqy. I have tested the lib itself in Query Console, all functions run fine.
The alert action itself also runs fine in QC.
The simpleTrigger works ok.
The more complex one runs IF I REMOVE the function that uses my own lib.
Seems that the trigger is run by a user or from a place where it cannot find my module (which is in the modules db). I have set the trigger-db to point to the content-db.
The triggers look at a directory for new documents (document create).
If I want to use my own lib function the Error thrown is:
[1.0-ml] XDMP-MODNOTFOUND: (err:XQST0059) xdmp:eval("xquery version
"1.0-ml";
let $uri := '/marklo...", (),
<options xmlns="xdmp:eval"><database>12436607035003930594</database>
<modules>32519102440328...</options>)
-- Module /lib/sccss-lib.xqy not found
The module is in the modules-db...
Another thing that bothers me is the example in ML doc does a
xdmp:document-insert("/modules/log.xqy",
text{ "
xquery version '1.0-ml';
..."
}, xdmp:permission('app-user', 'execute'))
What does the permission app-user do in this case?
Anyway main question: Why does the trigger not run if I use a custom module in the trigger action?
I have seen this question and think it is related but I do not understand the answer there...
EDIT start, more information on the trigger create statement:
xquery version "1.0-ml";
import module namespace trgr="http://marklogic.com/xdmp/triggers"
at "/MarkLogic/triggers.xqy";
trgr:create-trigger("sensorTrigger", "Simple trigger for connection systems sensor, the action checks how long this device is around the sensor",
trgr:trigger-data-event(
trgr:directory-scope("/marklogic.solutions.obi/source/", "1"),
trgr:document-content("create"),
trgr:post-commit()),
trgr:trigger-module(xdmp:database("cluey-app-content"), "/triggers/", "check-time-at-sensor.xqy"),
fn:true(), xdmp:default-permissions() )
Also indeed the trigger is created from the QC, so indeed as admin(I yet have to figure out how to do that adding code to app-specific.rb). And also the trigger action is loaded from the QC with a doc insert statement equivalent as the trigger example in the docs.
For completeness I added this to app-specific.rb per suggestion by Geert
alias_method :original_deploy_modules, :deploy_modules
def deploy_modules()
original_deploy_modules
# and apply correct permissions
r = execute_query %Q{
xquery version "1.0-ml";
for $uri in cts:uris()
return (
$uri,
xdmp:document-set-permissions($uri, (
xdmp:permission("#{#properties["ml.app-name"]}-role", "read"),
xdmp:permission("#{#properties["ml.app-name"]}-role", "execute")
))
)
},
{ :db_name => #properties["ml.modules-db"] }
end
For testing I also loaded it as part of the content (using ./ml local deploy content to load it, as said before the action is there it will run so there seems no issue with the permission of the action doc itself. What I do not understand is that as soon as I try to use my own module in the action it fails to find the module or(see comment David) does not have the right permission on the module. So the trigger action will fail to run ... The module is loaded with roxy under /src/lib/lib.xqy
SECOND EDIT
I added all trigger stuf to include in roxy by adding the following to app_specific.rb:
# HK voor gebruik modules die geen REST permissies hebben in een rest extension
alias_method :original_deploy_modules, :deploy_modules
def deploy_modules()
original_deploy_modules
# Create triggers
r = execute_query(%Q{
xquery version "1.0-ml";
import module namespace trgr="http://marklogic.com/xdmp/triggers"
at "/MarkLogic/triggers.xqy";
xdmp:log("Installing triggers.."),
try {
trgr:remove-trigger("sensorTrigger")
} catch ($ignore) {
};
xquery version "1.0-ml";
import module namespace trgr="http://marklogic.com/xdmp/triggers"
at "/MarkLogic/triggers.xqy";
trgr:create-trigger("sensorTrigger", "Trigger to check duration at sensor",
trgr:trigger-data-event(
trgr:directory-scope("/marklogic.solutions.obi/source/", "1"),
trgr:document-content("create"),
trgr:post-commit()
),
trgr:trigger-module(xdmp:modules-database(), "/", "/triggers/check-time-at-sensor.xqy"),
fn:true(),
xdmp:default-permissions(),
fn:false()
)
},
######## THIRD EDIT ###############
#{ :app_name => #properties["ml.app-name"] }
{ :db_name => #properties["ml.modules-db"] }
)
# and apply correct permissions
r = execute_query %Q{
xquery version "1.0-ml";
for $uri in cts:uris()
return (
$uri,
xdmp:document-set-permissions($uri, (
xdmp:permission("#{#properties["ml.app-name"]}-role", "read"),
xdmp:permission("#{#properties["ml.app-name"]}-role", "execute")
))
)
},
{ :db_name => #properties["ml.modules-db"] }
end
As you can seee the rootpath is now "/" in line
trgr:trigger-module(xdmp:modules-database(), "/", "/triggers/check-time-at-sensor.xqy")
I also added permissions by hand but still as soon as I add the line pointing to sccs-lib.xqy my trigger fails...
There is a number of criteria that need to be met for a trigger to work properly. David already mentioned part of them. Let me try to complete the list:
You need to have a database that contains the trigger definition. That is the database against which the trgr:create-trigger was executed. Typically Triggers or some app-triggers.
That trigger database needs to be assigned as triggers-database to the content database (not the other way around!).
You point to a trigger module that contains the code that will get executed as soon as a trigger event occurs. The trgr:trigger-module explicitly points to the uri of the module, and the database in which it is contained.
Any libraries used by that trigger module, need to be in the same database as the trigger module. Typically both trigger module, and related libraries are stored within Modules or some app-modules.
With regard to permissions, the following applies:
First of all, you need privileges to insert the document (uri, and collection).
Then, to be able to execute the trigger, the user that does the insert needs to have a role (directly, inherited, or via amps) that has read and execute permission on the trigger modules, as well on all related libraries.
Then that same user needs to have privileges to do whatever the trigger modules needs to do.
Looking at your create-triggers statement, I notice that the trigger module is pointing to the app-content database. That means it will be looking for libraries in the app-content database as well. I would recommend putting trigger module, and libraries in the app-modules database.
Also, regarding app-user execute permission: that is just a convention. The nobody user has the app-user role. That is typically used to allow the nobody user to run rewriter code.
HTH!
Could you please provide a bit more information - like perhaps the entire trigger create statement?
For creating the trigger, keep in mind:
the trigger database that you insert the trigger into has to be the one defined in the content database you refer to in the trigger and
trgr:trigger-module allows you to define the module database and the module to run. With this defined properly, then I cannot see how /lib/sccss-lib.xqy is not found - unless it is a permissions item...
Now on to the other item in your question: you test stuff in query console. That has the roles of that user - often run by people as admin... MarkLogic gives a 'not found' message also if a document is there - and you simply do not have access to it. So, it is possible that there is a problem with permissions for the documents in your modules database.
I am confused about passing data from database (mongodb) to html.
I have python code in "init.py" that queries database using while logic - see below code snippet:
from pymongo import MongoClient
from flask import Flask, render_template
#app.route("/snapshot")
def pymongo_query():
db=client.collection
months=[1,2,3,4,5,6,7,8,9,10,11,12]
while months:
mon=months.pop()
query=list(db.collection.find({args}))
query=query[0]
month=query['month']
item_1=query['item_1']
item_2=query['item_2']
What this codes does is it goes through each month represented by number in list and queries database for the respective month. I use while loop to go over months. In Python I would use print at the end of loop to output result.
How do I output data into html using jinja2? I was wondering if I need to have while logic in jinja or keep it as I have it right now in init.py file above.
I hope this will help you.
You can pass the arguments item_1,item_2,month etc. to HTMLfile by adding these to a list or dictionary.
list=[month,item_1,item_2]
or
list=[]
list.append(month)
list.append(item_1)
list.append(item_2)
and pass it as
#app.route('/')
def something():
return render_template("abc.html",my_list=list)
Now for using this in html (using jinja2)
add some code like:
<ul>
{% for n in my_list %}
<li>{{n}}</li>
{% endfor %}
</ul>
in your abc.html file.
Now run the init.py file again and check output.
Like the tutorial in the Flask docs demonstrates, you return a call to render_template, passing the information that the template needs to the call. All application and complex logic should stay out of the template. Assuming you've made a 'snapshot.html' template in the 'templates' folder, and assuming you do something to collect item_1 and item_2 in the while loop to a collection items:
return render_template('snapshot.html', items=items)
I am trying to add the DOCTYPE declaration to an output XML file using Xerces 2.8
I am using DOMDocument* doc1 = implementation->createDocument(); to create the document
and I want to add the doctype from doc to doc1.
I could obtain the doctype from doc as follow:
DOMDocumentType* document_type = doc->getDoctype();
However, I can not pass document_type to the function createDocument().
Does anyone has an example of how to do this?
Thank you,
Gilmer
You have to set the "http://xml.org/sax/properties/lexical-handler" property of your Xerces instance to an object of type "LexicalHandler". You will be informed about any events over the "startDTD" callback. This is at least true for Java. Should be identical for C.