User

Difference between revisions of "Nicolas NALLET"

(les éléments avec un ID sont isolés, c’est plus simple à gérer avec du JS pour remplacer tout le contenu)
Line 1: Line 1:
Consultant MediaWiki chez [https://wiki-valley.com Wiki Valley]
+
// Development in final phase of the interface for displaying contributions
 +
$( function (){
 +
if( mw.config.get( 'wgPageName' ) !== 'User:Nicolas_NALLET' ) {
 +
return;
 +
}
 +
var userLanguage = mw.config.get( 'wgUserLanguage' );
 +
var messages = {
 +
'no-results': {
 +
en: 'No results.',
 +
de: 'Keine Ergebnisse.',
 +
fr: 'Pas de résultat.',
 +
}
 +
};
 +
mw.loader.using( ['oojs', 'oojs-ui'], function () {
  
<span class="mwc">MediaWiki Consultant</span> at [https://en.wiki-valley.com Wiki Valley]
+
oouiSelectors = {
 +
'speaker': null,
 +
'gender': null,
 +
'language': null,
 +
'proficiency': null,
 +
};
 +
var sparqlGlobal = {
 +
'speaker': 'SELECT DISTINCT ?speaker ?speakerLabel WHERE { ?speaker prop:P2 entity:Q3 . ?speaker rdfs:label ?speakerLabel . FILTER( LANG(?speakerLabel) = "en" ) } ORDER BY ?speakerLabel',
 +
'gender': 'SELECT DISTINCT ?gender ?genderLabel WHERE { ?gender prop:P2 entity:Q7 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?gender',
 +
'language': 'SELECT DISTINCT ?language ?languageLabel WHERE { ?language prop:P2 entity:Q4 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?languageLabel',
 +
'proficiency': 'SELECT DISTINCT ?proficiency ?proficiencyLabel WHERE { ?proficiency prop:P2 entity:Q5 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?proficiency',
 +
};
 +
var placeholders = {
 +
'en': {
 +
'speaker': '👤 Speaker',
 +
'gender': '♀️ ♂️ Speaker\'s gender',
 +
'language': '🏳️ Language',
 +
'proficiency': '🥇 Level of proficiency',
 +
},
 +
'fr': {
 +
'speaker': '👤 Locuteur',
 +
'gender': '♀️ ♂️ Genre du locuteur',
 +
'language': '🏳️ Langue',
 +
'proficiency': '🥇 Niveau de compétence',
 +
},
 +
};
 +
var htmlElements = {
 +
'speaker': '#filteruser',
 +
'gender': '#filtergender',
 +
'language': '#filterlanguage',
 +
'proficiency': '#filterlevelofproficiency',
 +
};
 +
var lastRequest = {
 +
'speaker': '',
 +
'gender': '',
 +
'language': '',
 +
'proficiency': '',
 +
};
  
<h1 id="firstHeading">Find a record by language, user or level of proficiency</h1>
+
function getValueWidget( type ) {
 +
if( !oouiSelectors[type] ) {
 +
return '';
 +
}
 +
var widgetCombobox = type === 'speaker' || type === 'language';
 +
if( widgetCombobox ) {
 +
return oouiSelectors[type].getValue();
 +
} else {
 +
return oouiSelectors[type].getMenu().findSelectedItem() ? oouiSelectors[type].getMenu().findSelectedItem().getData() : '';
 +
}
 +
 +
}
  
<div style="float:right">
+
function updateSelector( type ) {
==Results==
+
return function( values ) {
<div id="audioresults"></div>
+
if( ( getValueWidget( 'speaker' ) != lastRequest['speaker'] ) ||
<!--<div class="audiobox">
+
    ( getValueWidget( 'gender' ) != lastRequest['gender'] ) ||
    <div class="ab-playbutton"><i></i></div>
+
    ( getValueWidget( 'language' ) != lastRequest['language'] ) ||
    <div>
+
    ( getValueWidget( 'proficiency' ) != lastRequest['proficiency'] ) ) {
        <div class="ab-title">...</div>
+
return;
        <div class="ab-metadata">...</div>
+
}
    </div>
 
</div>-->
 
  
</div>
+
var widgetType = type === 'speaker' || type === 'language' ? 'ComboBoxInputWidget' : 'DropdownWidget';
 +
var v = values.results.bindings;
 +
console.log( type );
 +
console.log( v );
 +
console.log( v.length === 1 ? v[0][ type + 'Label' ].value + " (" + v[0][type].value.substr( 31 ) + ")" : null );
 +
oouiSelectors[type] = new OO.ui[widgetType]( {
 +
placeholder: placeholders[userLanguage][type] ? placeholders[userLanguage][type] : placeholders['en'][type],
 +
disabled: v.length === 1,
 +
value: v.length === 1 ? v[0][ type + 'Label' ].value + " (" + v[0][type].value.substr( 31 ) + ")" : null,
 +
menu: {
 +
filterFromInput: true,
 +
items: v.map( function( x ) {
 +
return new OO.ui.MenuOptionWidget( {
 +
data: x[ type + 'Label' ].value + " (" + x[type].value.substr( 31 ) + ")",
 +
label: x[ type + 'Label' ].value
 +
} );
 +
} )
 +
}
 +
} );
  
<div style="background-color: #206ae2; color: white; height:500px; width: 300px">
+
$( htmlElements[type] ).html('').append(
<span style="margin-left: 40px;color: white;">Select a Speaker<span id="filteruser"></span></span>
+
oouiSelectors[type].$element
 +
);
  
<span style=" margin-left: 40px;color: white;">Select a Speaker's genre<span id="filtergender"></span></span>
+
oouiSelectors[type].on( 'change', function() { doQuery(); doQuery( 'speaker' ); doQuery( 'gender' ); doQuery( 'language' ); doQuery( 'proficiency' ); } );
  
<span style=" margin-left: 40px;color: white;">Select a Language<span id="filterlanguage"></span></span>
+
};
 +
}
  
<span style=" margin-left: 40px;color: white;">Select a Level of proficiency<span id="filterlevelofproficiency"></span></span>
+
$.getJSON(
 +
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 +
{
 +
query: sparqlGlobal['speaker']
 +
}
 +
).done( updateSelector( 'speaker' ) );
  
<span id="savefiltersearch" style=" margin-left: 40px;color: white;"> 💾 Export this query in csv </span>
+
$.getJSON(
 +
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 +
{
 +
query: sparqlGlobal['gender']
 +
}
 +
).done( updateSelector( 'gender' ) );
  
</div>
+
$.getJSON(
 +
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 +
{
 +
query: sparqlGlobal['language']
 +
}
 +
).done( updateSelector( 'language' ) );
  
----
+
$.getJSON(
End of records page
+
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
__NOTOC__
+
{
==Sandbox==
+
query: sparqlGlobal['proficiency']
https://en.wikipedia.org/wiki/fr:H%C3%B4tel+de+la+Roche-Guyon
+
}
 +
).done( updateSelector( 'proficiency' ) );
  
==OOui==
+
// Display results
<div class="wrapper">
+
function createAudioBoxesForSearch( data ) {
<h1>Demo ToDo app with OOUI</h1>
+
if ( data.results === undefined || data.results.bindings === undefined ) {
</div>
+
displayError( 'error: no result from SPARQL' );
 +
return;
 +
}
 +
if ( data.results.bindings.length < 1 ) {
 +
$( '#audioresults' ).html( messages['no-results'][userLanguage] ? messages['no-results'][userLanguage] : messages['no-results']['en'] );
 +
return;
 +
}
 +
var length = data.results.bindings.length < 100 ? data.results.bindings.length : 100;
 +
$( '#audioresults' ).html( '' );
 +
for (var i = 0; i < length; i++) {
 +
var box = $( '<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>' );
 +
var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box );
 +
$( '#audioresults' ).append( box );
 +
//ab1 = new AudioBox( data.query.rwrecords[ i ], $( '.audiobox' ).eq( i ) );
 +
//$("body").append('<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>');
 +
}
 +
}
  
 +
// Do SPARQL request from filters
 +
function doQuery( variable ){
  
 +
// Do not modify a selector where there is a value
 +
if( variable && getValueWidget( variable ) ) {
 +
return;
 +
}
  
===[https://lingualibre.org/wiki/LinguaLibre:Chat_room#Browsing_the_sound_library Cahier des charges]===
+
function getQ( type ) {
* liste des enregistrements pour la sélection (avec un design similaire aux 2 derniers enregistrements sur la page d’accueil)
+
if( variable === type ) {
* sélecteurs :
+
return '?' + type;
** by language
+
}
** by speaker
+
var text = getValueWidget( type );
*** by speaker's language proficiency (beginner, etc.)
+
if( !text ) {
*** by speaker's genre (male, female, etc.)
+
return '';
** by cat (deepcat, incategory)
+
}
** by coord (nearcoord, boost-nearcoord)
+
text = text.trim();
** by link (linksto)
+
if( /^Q[0-9]+$/.test( text ) ) {
 +
return 'entity:' + text;
 +
} else if( /\((Q[0-9]+)\)$/.test( text ) ) {
 +
return 'entity:' + text.replace( /.*\((Q[0-9]+)\)$/, '$1' );
 +
} else {
 +
console.warn( 'Bad input “' + text + '”' );
 +
return '';
 +
}
 +
}
  
===Prototype===
+
var speaker = getQ( 'speaker' ),
 +
    gender = getQ( 'gender' ),
 +
    language = getQ( 'language' ),
 +
    proficiency = getQ( 'proficiency' ),
 +
    somevalue = false;
 +
if( ! variable ) {
 +
lastRequest = {
 +
'speaker': getValueWidget( 'speaker' ),
 +
'gender': getValueWidget( 'gender' ),
 +
'language': getValueWidget( 'language' ),
 +
'proficiency': getValueWidget( 'proficiency' ),
 +
};
 +
}
  
 +
var query = "SELECT " + ( variable ? 'DISTINCT ?' + variable + ' ?' + variable + 'Label' : "?record" ) + " WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . ";
 +
if( speaker ) {
 +
query += "?record prop:P5 " + speaker + " . ";
 +
somevalue = true;
 +
}
 +
if( gender ) {
 +
query += "?record prop:P5 [ prop:P8 " + gender + " ] . ";
 +
somevalue = true;
 +
}
 +
if( language ) {
 +
query += "?record prop:P4 " + language + " . ";
 +
somevalue = true;
 +
}
 +
if( proficiency ) {
 +
query += "?speaker llp:P4 [ llv:P4 ?language ; llq:P16 " + proficiency + " ] . ";
 +
somevalue = true;
 +
}
 +
query += "SERVICE wikibase:label { bd:serviceParam wikibase:language '" + userLanguage + ",en,fr' } } LIMIT 100";
  
<nowiki><div class="wrapper"></nowiki>
+
if( variable ) {
<div class="wrapper">
+
if( !somevalue ) {
<h1>Demo ToDo app with OOUI</h1>
+
query = sparqlGlobal[variable];
</div>
+
}
 +
} else {
 +
if( !variable && !somevalue ) {
 +
return;
 +
}
 +
$( '#audioresults' ).html( '' ); // TODO replace by a spinner
 +
}
  
 +
// Execute the request
 +
var result = $.getJSON(
 +
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 +
{
 +
query: query,
 +
//Accept: 'application/sparql-results+json'
 +
}
 +
);
  
Voir code dans [[MediaWiki:Common.js]]
+
// Depending if we want the whole results or update on selector
 +
if( variable ) {
 +
result.then( updateSelector( variable ), displayError );
 +
} else {
 +
result.then( createAudioBoxesForSearch, displayError );
 +
}
 +
}
  
==Voir aussi==
+
} );
*Autres outils dispos dans [[Special:Version]] : [https://lingualibre.org/index.php?title=LinguaLibre:Stats&action=edit Exemple de requête].
+
 
*le JS de l’extension QueryViz pour faire une requête SPARQL [https://github.com/lingua-libre/QueryViz/blob/master/modules/ext.queryViz.QueryViz.js], notamment la fonction postQuery mais aussi loadFilterValues pour la façon de récupérer les résultats.
+
} );
*Une requête SPARQL qui charge indéfiniment LinguaLibre:Records
 

Revision as of 08:43, 27 August 2021

// Development in final phase of the interface for displaying contributions $( function (){ if( mw.config.get( 'wgPageName' ) !== 'User:Nicolas_NALLET' ) { return; } var userLanguage = mw.config.get( 'wgUserLanguage' ); var messages = { 'no-results': { en: 'No results.', de: 'Keine Ergebnisse.', fr: 'Pas de résultat.', } }; mw.loader.using( ['oojs', 'oojs-ui'], function () {

oouiSelectors = { 'speaker': null, 'gender': null, 'language': null, 'proficiency': null, }; var sparqlGlobal = { 'speaker': 'SELECT DISTINCT ?speaker ?speakerLabel WHERE { ?speaker prop:P2 entity:Q3 . ?speaker rdfs:label ?speakerLabel . FILTER( LANG(?speakerLabel) = "en" ) } ORDER BY ?speakerLabel', 'gender': 'SELECT DISTINCT ?gender ?genderLabel WHERE { ?gender prop:P2 entity:Q7 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?gender', 'language': 'SELECT DISTINCT ?language ?languageLabel WHERE { ?language prop:P2 entity:Q4 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?languageLabel', 'proficiency': 'SELECT DISTINCT ?proficiency ?proficiencyLabel WHERE { ?proficiency prop:P2 entity:Q5 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?proficiency', }; var placeholders = { 'en': { 'speaker': '👤 Speaker', 'gender': '♀️ ♂️ Speaker\'s gender', 'language': '🏳️ Language', 'proficiency': '🥇 Level of proficiency', }, 'fr': { 'speaker': '👤 Locuteur', 'gender': '♀️ ♂️ Genre du locuteur', 'language': '🏳️ Langue', 'proficiency': '🥇 Niveau de compétence', }, }; var htmlElements = { 'speaker': '#filteruser', 'gender': '#filtergender', 'language': '#filterlanguage', 'proficiency': '#filterlevelofproficiency', }; var lastRequest = { 'speaker': , 'gender': , 'language': , 'proficiency': , };

function getValueWidget( type ) { if( !oouiSelectors[type] ) { return ; } var widgetCombobox = type === 'speaker' || type === 'language'; if( widgetCombobox ) { return oouiSelectors[type].getValue(); } else { return oouiSelectors[type].getMenu().findSelectedItem() ? oouiSelectors[type].getMenu().findSelectedItem().getData() : ; }

}

function updateSelector( type ) { return function( values ) { if( ( getValueWidget( 'speaker' ) != lastRequest['speaker'] ) || ( getValueWidget( 'gender' ) != lastRequest['gender'] ) || ( getValueWidget( 'language' ) != lastRequest['language'] ) || ( getValueWidget( 'proficiency' ) != lastRequest['proficiency'] ) ) { return; }

var widgetType = type === 'speaker' || type === 'language' ? 'ComboBoxInputWidget' : 'DropdownWidget'; var v = values.results.bindings; console.log( type ); console.log( v ); console.log( v.length === 1 ? v[0][ type + 'Label' ].value + " (" + v[0][type].value.substr( 31 ) + ")" : null ); oouiSelectors[type] = new OO.ui[widgetType]( { placeholder: placeholders[userLanguage][type] ? placeholders[userLanguage][type] : placeholders['en'][type], disabled: v.length === 1, value: v.length === 1 ? v[0][ type + 'Label' ].value + " (" + v[0][type].value.substr( 31 ) + ")" : null, menu: { filterFromInput: true, items: v.map( function( x ) { return new OO.ui.MenuOptionWidget( { data: x[ type + 'Label' ].value + " (" + x[type].value.substr( 31 ) + ")", label: x[ type + 'Label' ].value } ); } ) } } );

$( htmlElements[type] ).html().append( oouiSelectors[type].$element );

oouiSelectors[type].on( 'change', function() { doQuery(); doQuery( 'speaker' ); doQuery( 'gender' ); doQuery( 'language' ); doQuery( 'proficiency' ); } );

}; }

$.getJSON( 'https://lingualibre.org/bigdata/namespace/wdq/sparql', { query: sparqlGlobal['speaker'] } ).done( updateSelector( 'speaker' ) );

$.getJSON( 'https://lingualibre.org/bigdata/namespace/wdq/sparql', { query: sparqlGlobal['gender'] } ).done( updateSelector( 'gender' ) );

$.getJSON( 'https://lingualibre.org/bigdata/namespace/wdq/sparql', { query: sparqlGlobal['language'] } ).done( updateSelector( 'language' ) );

$.getJSON( 'https://lingualibre.org/bigdata/namespace/wdq/sparql', { query: sparqlGlobal['proficiency'] } ).done( updateSelector( 'proficiency' ) );

// Display results function createAudioBoxesForSearch( data ) { if ( data.results === undefined || data.results.bindings === undefined ) { displayError( 'error: no result from SPARQL' ); return; } if ( data.results.bindings.length < 1 ) { $( '#audioresults' ).html( messages['no-results'][userLanguage] ? messages['no-results'][userLanguage] : messages['no-results']['en'] ); return; } var length = data.results.bindings.length < 100 ? data.results.bindings.length : 100; $( '#audioresults' ).html( ); for (var i = 0; i < length; i++) {

var box = $( '

...

' );

var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box ); $( '#audioresults' ).append( box ); //ab1 = new AudioBox( data.query.rwrecords[ i ], $( '.audiobox' ).eq( i ) );

//$("body").append('

...

');

} }

// Do SPARQL request from filters function doQuery( variable ){

// Do not modify a selector where there is a value if( variable && getValueWidget( variable ) ) { return; }

function getQ( type ) { if( variable === type ) { return '?' + type; } var text = getValueWidget( type ); if( !text ) { return ; } text = text.trim(); if( /^Q[0-9]+$/.test( text ) ) { return 'entity:' + text; } else if( /\((Q[0-9]+)\)$/.test( text ) ) { return 'entity:' + text.replace( /.*\((Q[0-9]+)\)$/, '$1' ); } else { console.warn( 'Bad input “' + text + '”' ); return ; } }

var speaker = getQ( 'speaker' ), gender = getQ( 'gender' ), language = getQ( 'language' ), proficiency = getQ( 'proficiency' ), somevalue = false; if( ! variable ) { lastRequest = { 'speaker': getValueWidget( 'speaker' ), 'gender': getValueWidget( 'gender' ), 'language': getValueWidget( 'language' ), 'proficiency': getValueWidget( 'proficiency' ), }; }

var query = "SELECT " + ( variable ? 'DISTINCT ?' + variable + ' ?' + variable + 'Label' : "?record" ) + " WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . "; if( speaker ) { query += "?record prop:P5 " + speaker + " . "; somevalue = true; } if( gender ) { query += "?record prop:P5 [ prop:P8 " + gender + " ] . "; somevalue = true; } if( language ) { query += "?record prop:P4 " + language + " . "; somevalue = true; } if( proficiency ) { query += "?speaker llp:P4 [ llv:P4 ?language ; llq:P16 " + proficiency + " ] . "; somevalue = true; } query += "SERVICE wikibase:label { bd:serviceParam wikibase:language '" + userLanguage + ",en,fr' } } LIMIT 100";

if( variable ) { if( !somevalue ) { query = sparqlGlobal[variable]; } } else { if( !variable && !somevalue ) { return; } $( '#audioresults' ).html( ); // TODO replace by a spinner }

// Execute the request var result = $.getJSON( 'https://lingualibre.org/bigdata/namespace/wdq/sparql', { query: query, //Accept: 'application/sparql-results+json' } );

// Depending if we want the whole results or update on selector if( variable ) { result.then( updateSelector( variable ), displayError ); } else { result.then( createAudioBoxesForSearch, displayError ); } }

} );

} );