User:TomT0m/queries/sandbox.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
// <syntaxhighlight lang="javascript">
/*jshint esversion: 8, esnext:false */
// Experiment : building query from high level tem{plates that generates SPARQL.
// Attempt to give a user interface to the [[Category:Partial query]] template members
(function () {
async function load_templates_in_category(api, name){
let pages = [];
let result;
do {
result = await api.get({
action:"query",
format:"json",
list:"categorymembers",
cmtitle:name,
cmnamespace:10,
cmlimit:500
});
pages = pages.concat(result.query.categorymembers);
} while (result.continue);
return pages;
}
function range_list(size, interval_len){
let rest = size % interval_len;
let num_intervals = (size - (rest)) / interval_len;
let ranges = Array.from({length: num_intervals}, (_, interval) => [interval * interval_len, ((interval+1) * interval_len) -1 ]);
if(rest !== 0){
let bound = interval_len * num_intervals;
ranges.push([bound, bound + rest]);
}
return ranges;
}
async function load_templatedatas(api, templates){
let results = {};
let range_size = 500;
let ranges = range_list(templates.length, range_size);
// https://www.wikidata.org/w/api.php?action=templatedata&format=json&titles=Template%3All&formatversion=2
for (let [min, max] of ranges){
let templatedatas = await api.get({
action:"templatedata",
format:"json",
titles: templates.slice(min, max)
});
for (let [id, page] of Object.entries(templatedatas.pages)){
results[page.title] = page;
}
}
return results;
}
function create_app(require) {
const Vue = require('vue');
const Pinia = require("pinia");
pinia = Pinia.createPinia();
const Codex = require('@wikimedia/codex');
const store = Pinia.defineStore("fragment", {
state : () => {
return {
fragments : [
{
id:1,
template: "Query instances",
params : [
{name:1, val:"?item", type:"variable"},
{name:2, val : "Q5", type:"item"}
],
},
{
id:2,
template: "Query instances",
params : [
{name:1, val:"?item", type:"variable"},
{name:2, val : "Q42", type:"item"}
],
}
]
};
},
actions: {
update_param(id, val) {
this.params.id = val;
}
}
});
const App = Vue.createMwApp({
template: `
<fragmentList/>
`,
}).use(pinia);
App.component('fragment', {
template:`<div style="background-color:Azure;margin:3px">
{{ fragment.template }} : [ <parameter v-for="param in fragment.params" :param="param" :key=param.name></parameter> ]</div>
`,
props:{ fragment : Object}
/*,
data() {
return {
template : store().template,
params : store().params
};
}*/
});
App.component("fragmentList", {
template:`
<ul>
<li v-for="fragment of fragments" >
<fragment :fragment="fragment" :key="fragment.id"></fragment>
</li></ul>
`,
data() {
return {
fragments : store().fragments
};
}
});
App.component("parameter", {
props: {param : Object},
template:`
<span style="margin:5px;">{{ param.name }} : {{ param.val }}</span>
`
});
/*
App.component('view', {
template: `
<div style="margin-bottom: 1rem">
{{ store.template }} : [ {{ <span v-for=param of store.params> param = store.params[param] ;</span>}}]
</div>
`,
setup: () => ({ store }),
components: {
CdxButton: Codex.CdxButton,
},
});*/
return App;
}
// load gadget
mw.loader.using( ['vue','pinia', '@wikimedia/codex', 'jquery.ui', 'mediawiki.api'], (require) => {
let app = create_app(require);
mw.util.addCSS(`
.query_editor_position {
position: absolute;
left: 300px;
top: 350px;
}`
);
mw.messages.set({
"queryfragment_link_title" : "Easy query",
"gadget_name" : "Easy query"
});
function listify(tab){
return $("<ul>").append(
tab.map((x, y) => $("<li>").append(x))
);
}
function install_menu_content(app_data_model){
const interface_container = `<div id="gadget-query-view"></div>`;
let popup = create_gadget_view(interface_container);
let popup_interface = $(".mw-page-container").append(popup.$element);
$("#gadget-query-view").append(
listify(Object.entries(app_data_model.templates).map(([title, template]) => title))
);
let link =$(mw.util.addPortletLink("p-tb", "#", mw.messages.get("queryfragment_link_title")));
link.on("click", ()=>popup.toggle(true ));
}
mw.hook('wikipage.content').add(
async (page_content)=>{
"use strict";
//console.log("Init function launched");
// console.log(page_content);
const config = {
fragment_site: "https://www.wikidata.org/" ,
fragment_category : "Category:Partial query",
talk_page_id_class : "FragmentQuery" // defined in Template:FragmentQuery div class to install the query editor components
};
// loading the datas
const api = new mw.Api(config.fragment_site + "/w/api.php");
async function get_templates_titles(){
return await load_templates_in_category(api, config.fragment_category);
}
let partial_pages = await get_templates_titles();
console.log(partial_pages);
let templatedatas = await load_templatedatas(api, partial_pages.map((x, y) => x.title));
console.log(templatedatas);
let app_data_model = { templates: templatedatas };
let apps_places = $("." + config.talk_page_id_class);
// install gadget views
$('#toc').before($('<div id="plop" class=""></div>'));
app.mount("#plop");
}
);
});
})();
// </syntaxhighlight>