TriplyDB / Yasgui

Yet Another Sparql GUI
https://yasgui.triply.cc
MIT License
190 stars 55 forks source link

Autocompleter Config #154

Closed ffritsche closed 4 years ago

ffritsche commented 4 years ago

Im try to write an autocompleter for classes and properties.

Yasgui.Yasqe.Autocompleters.prefixes.fetchFrom = "prefixlist.json";
Yasgui.defaults.requestConfig.endpoint = "http://ks2:8890/sparql";

Yasgui.defaults.catalogueEndpoints = [
    {
        endpoint: 'http://ks2:8890/sparql',
        title: 'Virtuoso WoS'
    }
];  

var customPropertyCompleterObj = {
        onInitialize: function(_yasqe) {
            return Yasqe.Autocompleters.property.onInitialize(_yasqe)
        },
        isValidCompletionPosition: function (yasqe) {
            return Yasqe.Autocompleters.property.isValidCompletionPosition(yasqe)
        },
        preProcessToken: function (yasqe, token) {
            return Yasqe.Autocompleters.property.preProcessToken(yasqe, token)
        },
        postProcessToken: function (yasqe, token, suggestedString) {
            return Yasqe.Autocompleters.property.postProcessToken(yasqe, token, suggestedString)
        }
};
customPropertyCompleterObj.name = "customPropertyCompleterObj";
//In this case we assume the properties will fit in memory. So, turn on bulk loading, which will make autocompleting a lot faster
customPropertyCompleterObj.bulk = true;
customPropertyCompleterObj.async = true;

//and, as everything is in memory, enable autoShowing the completions
customPropertyCompleterObj.autoShow = true;

customPropertyCompleterObj.get = function (token, callback) {

    //all we need from these parameters is the last one: the callback to pass the array of completions to
    var sparqlQuery = "SELECT distinct ?x WHERE { ?x a ?y. ?y rdfs:subClassOf* rdf:Property}";

    $.ajax({
        data: {
            query: sparqlQuery
        },
        url: Yasgui.defaults.requestConfig.endpoint,
        headers: {
            Accept: "application/sparql-results+json"
        },
        success: function (data) {
            var classes = [];
            data.results.bindings.forEach(function (b) {
                classes.push(b.x.value);
            });
            callback = classes;
        }
    });
};

//now register our new autocompleter
Yasqe.registerAutocompleter(customPropertyCompleterObj);

var customClassCompleterObj = {
        onInitialize: function(_yasqe) {
            return Yasqe.Autocompleters.class.onInitialize(_yasqe)
        },
        isValidCompletionPosition: function (yasqe) {
            return Yasqe.Autocompleters.class.isValidCompletionPosition(yasqe)
        },
        preProcessToken: function (yasqe,token) {
            return Yasqe.Autocompleters.class.preProcessToken(yasqe, token)
        },
        postProcessToken: function (yasqe, token, suggestedString) {
            return Yasqe.Autocompleters.class.postProcessToken(yasqe, token, suggestedString)
        }
};
customClassCompleterObj.name = "customClassCompleterObj";
customClassCompleterObj.bulk = true;
customClassCompleterObj.async = true;
customClassCompleterObj.autoShow = true;
customClassCompleterObj.get = function (token, callback) {
    var sparqlQuery = "SELECT distinct ?x  WHERE {?x rdfs:subClassOf []}";

    $.ajax({
        data: {
            query: sparqlQuery
        },
        url: Yasgui.defaults.requestConfig.endpoint,
        headers: {
            Accept: "application/sparql-results+json"
        },
        success: function (data) {
            var classes = [];
            data.results.bindings.forEach(function (b) {
                classes.push(b.x.value);
            });
            callback = classes;
        }
    });
};

Yasqe.registerAutocompleter(customClassCompleterObj);

//And, to make sure we don't use the other property and class autocompleters, overwrite the default enabled completers
Yasqe.defaults.autocompleters = ['prefixes', 'customClassCompleterObj', 'customPropertyCompleterObj', 'variables'];

const yasgui = new Yasgui(document.getElementById("yasgui"), {
    //Uncomment below to change the default endpoint
    //Note: If you've already opened the YASGUI page before, you should first clear your
    //local-storage cache before you will see the changes taking effect 
    requestConfig: { endpoint: "http://ks2:8890/sparql" },
    copyEndpointOnNewTab: false
});

I just cant get it to work and I cant find good examples for the new version of Yasgui. Also is there an way to extend the prefixlist? There was a option "fetchFrom" to set the url for the json prefixlist.

Thanks

LaurensRietveld commented 4 years ago

Creating a new completer (based on a different autocompleter), involves calling Yasqe.forkAutocompleter now. You can call that function with the autocompleter name that you want to copy from as first argument, and the properties that you want to overwrite as second argument.

For the list of allowed autocompleter properties, see https://github.com/TriplyDB/Yasgui/blob/5e5a12aa4d07337cba4301629ae8ca4a96ed6dde/packages/yasqe/src/autocompleters/index.ts#L9-L18

I.e., a simple example for creating a new class autocompleter would be:

Yasqe.forkAutocompleter('class', {
  name: "customClassCompleterObj",
  get: function(yasqe, token) {
    return Promise.resolve(['https://ex1.org', 'https://ex2.org'])
  }
})

You can use this same approach for adding custom prefix and property completers. If you have any suggestions for documentation improvements, feel free to mention them here, preferably with a PR!

ps. You'd also need to manually disable the original class completer by changing the Yasqe.defaults.completers setting. But, I'm thinking about doing that by default in the future when forking an autocompleter

ffritsche commented 4 years ago

Thanks, her is my solution:

Yasgui.defaults.requestConfig.endpoint = "http://ks2:8890/sparql";
Yasqe.forkAutocompleter('class', {
  name: "customClassCompleterObj",
  autoShow: true,
  bulk: true,
  async: true,
  //persistenceId: "customClassCompleterObj",
  get: function(yasqe, token) {
    var sparqlQuery = "SELECT distinct ?x  WHERE {?x rdfs:subClassOf []}";

    var classes = [];
    $.ajax({
        data: {
            query: sparqlQuery
        },
        url: Yasgui.defaults.requestConfig.endpoint,
        async: false, 
        headers: {
            Accept: "application/sparql-results+json"
        },
        success: function (data) {

            data.results.bindings.forEach(function (b) {
                classes.push(b.x.value);
            });

        }
    });

    return Promise.resolve(classes);
  }
})

Yasqe.forkAutocompleter('property', {
  name: "customPropertyCompleterObj",
  autoShow: true,
  bulk: true,
  async: true,
 // persistenceId: "customPropertyCompleterObj",
  get: function(yasqe, token) {

    //all we need from these parameters is the last one: the callback to pass the array of completions to
    var sparqlQuery = "SELECT distinct ?x WHERE { ?x a ?y. ?y rdfs:subClassOf* rdf:Property}";

    var properties = [];
    $.ajax({
        data: {
            query: sparqlQuery
        },
        url: Yasgui.defaults.requestConfig.endpoint,
        async: false,
        headers: {
            Accept: "application/sparql-results+json"
        },
        success: function (data) {

            data.results.bindings.forEach(function (b) {
                properties.push(b.x.value);
            });

        }
    });

    return Promise.resolve(properties);
  }
})

Yasqe.forkAutocompleter('prefixes', {
  name: "customPrefixCompleterObj",
  autoShow: true,
  bulk: true,
  async: true,
  persistenceId: "customPrefixCompleterObj",
  get: function(yasqe, token) {

    var prefixes = [];

    $.ajax({
        dataType: "json",
        url: "prefixlist.json",

        async: false,
        success: function (data) {
            entries = Object.entries(data);
            entries.forEach(entry => prefixes.push(entry[0]+": <"+entry[1]+">"));
        }
    });

    return Promise.resolve(prefixes);
  }
})

//And, to make sure we don't use the other property and class autocompleters, overwrite the default enabled completers
Yasqe.defaults.autocompleters = ['customPrefixCompleterObj', 'customClassCompleterObj', 'customPropertyCompleterObj', 'variables'];