Maryana has submitted this change and it was merged.

Change subject: Creative MaxSem friendly destruction: Wikidata Infoboxes in 
alpha
......................................................................


Creative MaxSem friendly destruction: Wikidata Infoboxes in alpha

This replaces infoboxes in alpha of the site with a Wikidata generated one.
The idea is we can use this to highlight missing data and use it as a basis
for wikidata games.

This is rough around the edges and needs lots of design love
abut I would say is alpha ready.

Example urls:
* http://localhost:8080/wiki/Albert_Einstein?wikidataid=Q937&mobileaction=alpha
* http://localhost:8080/wiki/Barack_Obama?mobileaction=alpha&wikidataid=Q76
* http://localhost:8080/wiki/Noam%20Chomsky?wikidataid=Q9049&mobileaction=alpha

Change-Id: I824d172e30d2b88ec7101e8dfa2ce9f6719c2ddf
---
M includes/Resources.php
A javascripts/modules/infobox/Infobox.js
A javascripts/modules/infobox/init.js
A less/modules/infobox.less
A templates/modules/infobox/Infobox.hogan
5 files changed, 353 insertions(+), 3 deletions(-)

Approvals:
  Maryana: Looks good to me, approved
  Bmansurov: Looks good to me, but someone else must approve



diff --git a/includes/Resources.php b/includes/Resources.php
index ef608ae..325201f 100644
--- a/includes/Resources.php
+++ b/includes/Resources.php
@@ -923,26 +923,52 @@
                ),
        ),
 
+       'mobile.wikigrok.api' => $wgMFResourceFileModuleBoilerplate + array(
+               'dependencies' => array(
+                       'mobile.startup',
+               ),
+               'scripts' => array(
+                       'javascripts/modules/wikigrok/WikiDataApi.js',
+                       'javascripts/modules/wikigrok/WikiGrokSuggestionApi.js',
+                       'javascripts/modules/wikigrok/WikiGrokResponseApi.js',
+               ),
+       ),
+
        // See https://www.mediawiki.org/wiki/Extension:MobileFrontend/WikiGrok
        'mobile.wikigrok.dialog' => $wgMFResourceFileModuleBoilerplate + array(
                'dependencies' => array(
                        'mobile.overlays',
                        'mobile.alpha',
+                       'mobile.wikigrok.api',
                ),
                'templates' => array(
                        'Dialog.hogan' => 
'templates/modules/wikigrok/WikiGrokDialog.hogan',
                        'WikiGrokMoreInfo/content.hogan' => 
'templates/modules/wikigrok/WikiGrokMoreInfo.hogan',
                ),
                'scripts' => array(
-                       'javascripts/modules/wikigrok/WikiDataApi.js',
-                       'javascripts/modules/wikigrok/WikiGrokSuggestionApi.js',
-                       'javascripts/modules/wikigrok/WikiGrokResponseApi.js',
                        'javascripts/modules/wikigrok/WikiGrokDialog.js',
                        'javascripts/modules/wikigrok/WikiGrokMoreInfo.js',
                ),
                'styles' => array(
                        'less/modules/wikigrok/WikiGrokDialog.less',
                ),
+       ),
+
+       'mobile.infobox' => $wgMFResourceFileModuleBoilerplate + array(
+               'dependencies' => array(
+                       'mobile.wikigrok.api',
+                       'mobile.ajax',
+               ),
+               'templates' => array(
+                       'Infobox.hogan' => 
'templates/modules/infobox/Infobox.hogan',
+               ),
+               'scripts' => array(
+                       'javascripts/modules/infobox/Infobox.js',
+               ),
+               'styles' => array(
+                       'less/modules/infobox.less',
+               ),
+               'position' => 'top',
        ),
 
        // Custom ResourceLoaderModule classes
@@ -1226,6 +1252,10 @@
                'dependencies' => array(
                        'mobile.beta',
                        // Feature modules that should be loaded in alpha 
should be listed below here.
+                       'mobile.infobox',
+               ),
+               'scripts' => array(
+                       'javascripts/modules/infobox/init.js',
                ),
        ),
        'tablet.scripts' => $wgMFResourceFileModuleBoilerplate + array(
diff --git a/javascripts/modules/infobox/Infobox.js 
b/javascripts/modules/infobox/Infobox.js
new file mode 100644
index 0000000..740da0b
--- /dev/null
+++ b/javascripts/modules/infobox/Infobox.js
@@ -0,0 +1,273 @@
+( function ( M, $ ) {
+       var Infobox,
+               WikiDataApi = M.require( 'modules/wikigrok/WikiDataApi' ),
+               View = M.require( 'View' );
+       /**
+        * A Wikidata generated infobox.
+        * FIXME: This currently requires 2 hits to the Wikidata API on every 
page load.
+        * @class Infobox
+        * @extends View
+        */
+       Infobox = View.extend( {
+               template: mw.template.get( 'mobile.infobox', 'Infobox.hogan' ),
+
+               className: 'wikidata-infobox',
+               defaults: {
+                       spinner: mw.template.get( 'mobile.ajax', 
'spinner.hogan' ).render(),
+                       description: mw.config.get( 'wgMFDescription' ) ||
+                               'A Wikipedia page in need of a description.',
+                       rows: []
+               },
+               typeDefaults: {
+                       // FIXME: In future this should be configurable by 
Wikipedia admins
+                       human: {
+                               rows: [
+                                       {
+                                               id: 'P18'
+                                       },
+                                       {
+                                               id: 'P569',
+                                               label: 'Born'
+                                       },
+                                       {
+                                               id: 'P19',
+                                               label: 'Birthplace'
+                                       },
+                                       {
+                                               id: 'P570',
+                                               label: 'Died'
+                                       },
+                                       {
+                                               id: 'P20',
+                                               label: 'Place of death'
+                                       },
+                                       {
+                                               id: 'P27',
+                                               label: 'Country of citizenship'
+                                       },
+                                       // FIXME: Add political party
+                                       {
+                                               id: 'P26',
+                                               label: 'Spouse(s)'
+                                       }, {
+                                               id: 'P25',
+                                               label: 'Mother(s)'
+                                       }, {
+                                               id: 'P22',
+                                               label: 'Father(s)'
+                                       },
+                                       //FIXME: Add Stepfather(s) (P43) and 
step mothers?
+                                       {
+                                               id: 'P9',
+                                               label: 'Sister(s)'
+                                       },
+                                       {
+                                               id: 'P7',
+                                               label: 'Brother(s)'
+                                       },
+                                       {
+                                               id: 'P40',
+                                               label: 'Child(ren)'
+                                       },
+                                       // FIXME: add residence?
+                                       {
+                                               id: 'P69',
+                                               label: 'Alma mater'
+                                       },
+                                       {
+                                               id: 'P106',
+                                               label: 'Occupation'
+                                       },
+                                       {
+                                               id: 'P108',
+                                               label: 'Employer(s)'
+                                       },
+                                       {
+                                               id: 'P140',
+                                               label: 'Religion'
+                                       },
+                                       // FIXME: add awards?
+                                       {
+                                               id: 'P109',
+                                               label: 'Signature'
+                                       },
+                                       {
+                                               id: 'P856',
+                                               label: 'Official website'
+                                       }
+                               ]
+                       },
+                       default: {
+                               description: undefined,
+                               rows: [
+                                       {
+                                               id: 'P856',
+                                               label: 'Official website'
+                                       }
+                               ]
+                       }
+               },
+               /**
+                * Parses a list of claims
+                *
+                * @private
+                * @method
+                * @param {Object} claims as returned by WikiData#getClaims
+                * @return {Array} List of values matching that claim
+                */
+               _getValues: function ( claims ) {
+                       var values = [];
+
+                       $.each( claims, function ( i, claim ) {
+                               var snak = claim.mainsnak,
+                                       value = snak.datavalue;
+                               if ( snak.snaktype === 'novalue' ) {
+                                       values.push( {
+                                               value: 'None'
+                                       } );
+                               } else if ( snak.datatype === 'commonsMedia' ) {
+                                       values.push( {
+                                               url: mw.util.getUrl( 'File:' + 
value.value ),
+                                               // FIXME: Map this to the image 
src
+                                               value: value.value
+                                       } );
+                               } else if ( value.type === 'string' ) {
+                                       values.push( {
+                                               value: value.value
+                                       } );
+                               } else if ( value.type === 'time' ) {
+                                       values.push( {
+                                               // FIXME: This should be more 
readable. Usually time is not important.
+                                               value: new Date( 
value.value.time.substr( 8 ) )
+                                       } );
+                               } else if ( value.type === 'wikibase-entityid' 
) {
+                                       values.push( {
+                                               id: 'Q' + value.value[ 
'numeric-id' ],
+                                               isLink: true
+                                       } );
+                               } else if ( value.type === 'globecoordinate' ) {
+                                       values.push( {
+                                               value: value.value.latitude + 
', ' + value.value.longitude
+                                       } );
+                               } else if ( value.type === 'quantity' ) {
+                                       // FIXME: Deal with qualifiers
+                                       values.push( {
+                                               value: value.value.amount
+                                       } );
+                               } else {
+                                       console.log( value.type + ' unknown', 
value );
+                               }
+                       } );
+                       return values;
+               },
+               /**
+                * Translates IDs in the current row value to human readable 
text
+                *
+                * @private
+                * @method
+                * @param {Array} rows with id and label
+                * @return {Array} rows with human readable values
+                */
+               _mapLabels: function ( rows ) {
+                       var labelIds = [];
+
+                       // collect all the label ids
+                       $.each( rows, function ( i, row ) {
+                               $.each( row.values, function ( i, value ) {
+                                       if ( value.id ) {
+                                               labelIds.push( value.id );
+                                       }
+                               } );
+                       } );
+
+                       // work out what they all mean
+                       return this.api.getLabels( labelIds ).then( function ( 
labels ) {
+                               // map the property id to the actual label.
+                               $.each( rows, function ( i, row ) {
+                                       $.each( row.values, function ( j, value 
) {
+                                               if ( labels[ value.id ] ) {
+                                                       value.value = labels[ 
value.id ];
+                                                       value.url = 
mw.util.getUrl( value.value );
+                                               }
+                                       } );
+                               } );
+                               return rows;
+                       } );
+               },
+               /**
+                * Decides based on the type of item what infobox to render
+                *
+                * @private
+                * @method
+                * @param {Object} claims as returned by WikiData#getClaims
+                * @return {Object} default option values
+                */
+               getDefaultsFromClaims: function ( claims ) {
+                       if ( claims.isHuman ) {
+                               return this.typeDefaults.human;
+                       } else {
+                               return this.typeDefaults.default;
+                       }
+               },
+               /**
+                * @inheritdoc
+                */
+               initialize: function ( options ) {
+                       this.api = new WikiDataApi( {
+                               itemId: options.itemId
+                       } );
+
+                       View.prototype.initialize.apply( this, arguments );
+               },
+               /**
+                * @inheritdoc
+                */
+               postRender: function( options ) {
+                       var _loadRest = this._loadRest,
+                               self = this;
+
+                       this.$( '.spinner' ).hide();
+                       this.$( '.more' ).on( 'click', function() {
+                               $( this ).remove();
+                               _loadRest.call( self, options );
+                       } );
+               },
+               /**
+                * Decides based on the type of item what infobox to render
+                *
+                * @private
+                * @method
+                */
+               _loadRest: function( options ) {
+                       var self = this,
+                               _super = View.prototype.render;
+
+                       this.$( '.spinner' ).show();
+                       this.api.getClaims().done( function ( claims ) {
+                               var rows;
+                               options = $.extend( options, 
self.getDefaultsFromClaims( claims ) );
+                               options.description = claims.description;
+                               rows = options.rows;
+                               $.each( rows, function ( i, row ) {
+                                       if ( claims.entities[ row.id ] ) {
+                                               row.values = self._getValues( 
claims.entities[ row.id ] );
+                                       } else {
+                                               row.values = [];
+                                       }
+                                       row.isEmpty = !( row.values && 
row.values.length );
+                               } );
+
+                               self._mapLabels( rows ).done( function ( rows ) 
{
+                                       options.rows = rows;
+                                       _super.call( self, options );
+                               } );
+                       } ).fail( function () {
+                               // remove spinner
+                               self.$el.remove();
+                       } );
+               }
+       } );
+
+       M.define( 'modules/wikigrok/Infobox', Infobox );
+
+}( mw.mobileFrontend, jQuery ) );
diff --git a/javascripts/modules/infobox/init.js 
b/javascripts/modules/infobox/init.js
new file mode 100644
index 0000000..981fa4c
--- /dev/null
+++ b/javascripts/modules/infobox/init.js
@@ -0,0 +1,16 @@
+( function ( M, $ ) {
+       M.assertMode( [ 'alpha' ] );
+       var infobox,
+               wikidataID = mw.config.get( 'wgWikibaseItemId' ),
+               Infobox = M.require( 'modules/wikigrok/Infobox' );
+
+       if ( wikidataID ) {
+               // upset people
+               $( '.infobox' ).hide();
+               // build the future
+               infobox = new Infobox( {
+                       itemId: wikidataID
+               } );
+               infobox.insertBefore( '#content' );
+       }
+}( mw.mobileFrontend, jQuery ) );
diff --git a/less/modules/infobox.less b/less/modules/infobox.less
new file mode 100644
index 0000000..ec72b98
--- /dev/null
+++ b/less/modules/infobox.less
@@ -0,0 +1,17 @@
+@import "minerva.variables";
+@import "minerva.mixins";
+
+.wikidata-infobox {
+       padding: 0 1em 2em;
+       margin: 0 0 1em;
+       border: solid 1px @grayLight;
+       border-top: none;
+       background-color: @grayLightest;
+}
+
+@media all and (min-width: @wgMFDeviceWidthTablet) {
+       .wikidata-infobox {
+               max-width: 893px;
+               margin: 0 auto;
+       }
+}
diff --git a/templates/modules/infobox/Infobox.hogan 
b/templates/modules/infobox/Infobox.hogan
new file mode 100644
index 0000000..0fd73cb
--- /dev/null
+++ b/templates/modules/infobox/Infobox.hogan
@@ -0,0 +1,14 @@
+<em>{{description}}</em>
+{{^rows}}
+<button class="mw-ui-button mw-ui-quiet mw-ui-progressive 
more">expand…</button>
+{{/rows}}
+{{{spinner}}}
+{{#rows}}
+<div>
+       {{^isEmpty}}{{#label}}<strong>{{label}}</strong>: {{/label}}{{/isEmpty}}
+       {{#values}}
+       {{#url}}<a href="{{url}}">{{value}}</a>{{/url}}
+       {{^url}}{{value}}{{/url}}
+       {{/values}}
+</div>
+{{/rows}}

-- 
To view, visit https://gerrit.wikimedia.org/r/172932
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I824d172e30d2b88ec7101e8dfa2ce9f6719c2ddf
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Jdlrobson <[email protected]>
Gerrit-Reviewer: Awjrichards <[email protected]>
Gerrit-Reviewer: Bmansurov <[email protected]>
Gerrit-Reviewer: Maryana <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to