Combine results of #ask subquery in semantic-mediawiki - mediawiki

I have a scientific paper collection stored in semantic mediawiki. The page is always the title of the paper. Every paper has a unique id in the form of the citekey property [[Has citekey::someauthor2019]].
Now, I want to link it to other publications and automatically show a table of all referenced papers. In order to do that I keep multiple properties per page with a reference property [[Has reference::authorX2017]], [[Has reference::authorY2018]], etc.
To achieve that I want to get all references with an #ask query and use these results in a new #ask query to get all results that have either of the references as their citekey property.
To acquire the references I use a combination of this #ask query:
{{#ask: [[Has citekey::someauthor2019]]
|?Has reference
|format=template
|template=Query Result
}}
with this Query Result format Template:
{{{2}}}
For example, this would lead to the output: authorX2017, authorY2018
How can I use this automatically in a new #ask query to obtain a list of the pages that have any of these references as their citekey property?
Thank you for any advise!

How can I use this in a new #ask query to obtain a list of the pages that have any of these references as their citekey property?
You should just use the result parameter as a new parameter of the inner ask query inside your template. Any trouble this way ?
Try to use
|link=none
(see source 1)
this will pass {{{1}}} and {{{2}}} results as raw text to your template
You request becomes :
{{#ask: [[Has citekey::someauthor2019]]
|?Has reference
|format=template
|template=Query Result
|link=none
}}
Then you can use {{{1}}} and {{{2}}} as parameters for a new query.
But, you said that you may have multiple results for the {{{has reference}}} result parameter. So you should use something like an arraymaptemplate (see source 2).
{{#arraymaptemplate:value|template|delimiter|new_delimiter}}
where 'template' will use each value of the {{{2}}} list in its own request.
Sources :
https://www.semantic-mediawiki.org/wiki/Help:Inline_queries#Standard_parameters_for_inline_queries
https://www.mediawiki.org/wiki/Extension:Page_Forms/Page_Forms_and_templates#arraymaptemplate

Related

Semantic Mediawiki: aggregation similar to SQL GROUP BY like #ask query

I've implemented a page with a long list of subojects.
Every object contains one article (title + url) and N tags. I'd like to group by tag and show the count of articles related to that tag.
Something like:
SELECT tag, count(distinct article)
GROUP BY tag
I found an answer but it's very generic and I'd also like to document the solution for other user with the same problem.
As you know from previous answers to this question, you cannot have a "distinct" function from an SMW ask query.
My preferred solution is to use the "arrays" extension, that allows you to access PHP array manipulation functions in wiki code. Further than "distinct" list of value, its an irreplaceable tool for handling semantic data from queries.
You can create an array with the following function :
{{#arraydefine: *identifier* | *data* | *delimiter* | *parameters* }}
Identifier is the variable name you want.
Data is the array content, in SMW context, you load it with a query result content.
Delimiter specify the array delimiter relative to data. This have to be
coherent with the delimiter chosen in the ask query.
Parameters is where the magic appends. You can set a "unique" parameter, reducing the data list to unique values, thus, emulating the "distinct" function.
In tour case, you may do something like :
{{#arraydefine:tags
| {{#ask:[[-Has subobject::{{FULLPAGENAME}}]]
|?Tags#-=
| mainlabel=-
|limit = 1000
}}
|,
|unique
}}
Note that SMW ask query are, by default, limited to 50 results. Adding "limit=" adjusts the maximum result size.
At this point, you defined an array called "tags" containing all distinct values of this property.
You can use arrayprint function for any further data treatment or display.

Wikipedia Mediawiki API get URL in query

Using the MediaWiki API I have a query that returns the results I want:
https://en.wikipedia.org/w/api.php?action=query&list=allpages&apfrom=Apple&aplimit=5
How can I modify it to also include the URL for each of the pages that are returned?
I tried adding the "info" property and "url" info, but it does not return additional information:
https://en.wikipedia.org/w/api.php?action=query&list=allpages&apfrom=Apple&aplimit=5&prop=info&inprop=url
You need to move the parameters you use to get the result to a generator instead of a list and then use prop=info and inprop=url in the query. Like this:
https://en.wikipedia.org/w/api.php?action=query&format=json&prop=info&generator=allpages&inprop=url&gapfrom=Apple&gaplimit=5

Passing properties in Semantic MediaWiki

Currently I have 3 categories, Application, Application Instance and Vendor.
Right now Application has a link (via property Made By) to Vendor. Application instances need to link back to Vendor via a property. I have the query I can use to return the application name and vendor is
{{#ask:
[[Category:Program]][[{{{Program}}}]]
|?Made By
}}
however
{{#set:Made By={{#ask:
[[Category:Program]][[{{{Program}}}]]
|?Made By
}}}}
doesn't work to set the property to the value of vendor which is returned by the ask query.
Are there other ways to do this?
Maybe a bit late but you could probably do this using a template to set the property. Something like this?
In the Application Instance template (or manually on each Application Instance page) add the following ask query:
{{#ask:[[Category:Program]][[{{{Program}}}]]
|?Made By
|link=none
|format=template
|template=Set made by
}}
Then create the template "wiki/Template:Set made by" with the following:
includeonly>
{{#set:
Made By={{{2}}}
}}
</includeonly>
Notes
Parameter {{{1}}} is the subject which is the page name and {{{2}}} will be the result for 'Made By'.
Stripping the link from the query results prevents the extra text being passed to the set command which would confuse things.
You can also use the inverse of properties in queries by adding a minus sign in front of them. (e.g. '-Made By')

Filter a rest service by category or field

I am using the extension library's rest control to provide a json data feed. Is it possible to filter by a category or a field with a URL parameter?
I understand that I can use a search string "&search=something" but that can provide me with erroneous results. I have tried searching for a field equal to some value but that doesn't seem to work for me.
If I cannot do this with the rest control, is it possible with Domino Data Services?
You can filter by a category or field value in a viewJsonService if you add ?keys=yourValue to URL.
The REST service returns the same documents as you would get with view.getAllDocumentsByKey("yourValue").
Default is non-exact-match filtering which means that only the beginning of column value has to match. If you want the exact match then add &keysexactmatch=true to URL which would be the equivalent to view.getAllDocumentsByKey("yourValue", true).
Example:
Assuming, we have a view "Forms" with a first sorted column "Form".
With the REST service
<xe:restService
id="restService1"
pathInfo="DocsByForm">
<xe:this.service>
<xe:viewJsonService
viewName="Forms"
defaultColumns="true">
</xe:viewJsonService>
</xe:this.service>
</xe:restService>
and the URL
http://server/database.nsf/RestServices.xsp/DocsByForm?keys=Memo&keysexactmatch=true
we'd get all documents with Form="Memo" as JSON
[
{
"#entryid":"7-D5029CB83351A9A6C1257D820031E927",
"#unid":"D5029CB83351A9A6C1257D820031E927",
"#noteid":"11DA",
"#position":"7",
"#siblings":14,
"#form":"Memo",
"Form":"Memo",
... other columns ...
},
... other documents
]
We'd get the same result if the first column is categorized.

Categories and Keywords access via Razor Template in Tridion

I am attempting to access values in the Categories and Keywords information for a Tridion Publication via a Razor TBB in Tridion 2011. The Razor documentation lists the following example code:
<ul>
#foreach (var keyword in Publication.MetaData.SomeKeywordFields) {
<li>#keyword.Title (#keyword.Id)</li>
}
</ul>
I have a Keyword inside of a Category though... in fact, that's the only way I am myself aware that you can even have a Keyword in Tridion, but correct me if I am wrong. Extrapolating from the example's syntax, I tried the following where "myCategory" is a Category in the publication, and "myKeyword" is a Keyword inside of the myCategory Category:
#foreach (var keyword in Publication.MetaData.myCategory) {
if(#keyword.Title == "myKeyword") {
#keyword.Title
}
When I run this template, I get an error stating that DynamicItemsFields: Key 'testcategory' Not Found In ItemFields (Object reference not set to an instance of an object)
Can anyone help with identifying if it is even possible to do what I am attempting here (as it seems like it is based on the documentation but still not sure) and if so, provide an example of the correct syntax?
You're almost there with your code except that you're using the actual CategoryName. As Puf commented, you have to use the "fieldname" of you Publication Metadata not the actual CategoryName. You should just change the "myCategory" to the actual fieldname
#foreach (var keyword in Publication.MetaData.*<<FIELDNAME>>*) {
if(#keyword.Title == "myKeyword") {
#keyword.Title
}
}
[FIELDNAME] --> is the XMLName of publication metadata schema.
Keywords are indeed always within a Category or another Keyword. But they are used within items like Components and (as in the example) metadata on Publications, Folders, etc.
The example from the documentation is outputting each value of a multi-valued metadata Keyword field on the Publication (i.e. "Allow Multiple Values", "Values selected from a list" and "Category" all checked in the Metadata Schema).
If you are trying to do something similar, you can indeed modify the name of the field and it will work. From your question, however, it seems like you are trying to loop over all Keywords within a certain Category - which requires a different approach.
For that, you would need the equivalent of a GetList call within your TBB. I'm not familiar enough with the Razor mediator to provide sample code for that, sorry.
Thanks to Ram G in chat:
The Publication itself, typically your 010, 020... 050 etc. levels, can have a metadata schema attached to them as well. The XMLName of the field being targeted by the Razor logic block above is actually the field name of this metadata schema item, not the name of the Category itself. In the metadata schema for the publication, if you select the Design tab, Make your XML field for the item a "Text" type, select "Options will be selected from a list", by default, another Checkbox will appear called "Category" which, if checked, automatically pulls in the full list of Category items present in that publication. So, when that Field is targeted by the Razor logic now, it is in multiple steps targeting the Category value as well.
Thanks again Ram G