Mollywhite has submitted this change and it was merged.
Change subject: Bug 50957: Populate navbar from JSON block.
......................................................................
Bug 50957: Populate navbar from JSON block.
The chapterlist, metadata, and previous/next links are now
populated from the page's corresponding JSON block. A category
on each section of the book (of the form
[[Category:Book:Book Title]]) indicates which Book: JSON block
belongs to the book. It then pulls in the JSON and populates
the navbar from that.
This is a pretty huge commit, and since I'm not just tweaking
someone else's code, I'm going to wait for some reviews before
merging this in.
Bug: 50957
Change-Id: I9c2d77ce649c678ae34343032ef68b2b673dc92e
---
M BookManagerv2.hooks.php
M BookManagerv2.i18n.php
2 files changed, 348 insertions(+), 59 deletions(-)
Approvals:
Mollywhite: Verified; Looks good to me, approved
jenkins-bot: Checked
diff --git a/BookManagerv2.hooks.php b/BookManagerv2.hooks.php
index c90fd35..868987d 100644
--- a/BookManagerv2.hooks.php
+++ b/BookManagerv2.hooks.php
@@ -5,6 +5,8 @@
* @file
* @ingroup Extensions
*
+ * @author Molly White
+ *
* @section LICENSE
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,95 +25,338 @@
class BookManagerv2Hooks {
- public static function readingInterfaceUX( $out, $prev, $next,
$chapterList, $metadata ) {
+ /**
+ * Adds a navigation bar to the page
+ *
+ * @param object $prev Object representing the preceding page; contains
+ * "link" and "name" properties.
+ * @param object $next Object representing the following page; contains
+ * "link" and "name" properties.
+ * @param string $chapterList String containing the chapter list HTML
+ * @param string $metadata String containing the metadata HTML
+ * @return string HTML string
+ */
+ public static function readingInterfaceUX( $prev, $next, $chapterList,
$metadata ) {
global $wgExtensionAssetsPath;
$imagePath = $wgExtensionAssetsPath . "/BookManagerv2/images/";
- $html = Html::openElement( 'div', array( 'class' =>
'mw-bookmanagerv2-nav-wrap' ) )
- . Html::openElement( 'div', array( 'class' =>
'mw-bookmanagerv2-nav-constrain' ) )
- . Html::openElement( 'div', array( 'class' =>
'mw-bookmanagerv2-nav-bar' ) )
- . Html::openElement( 'a', array(
+ $html = array();
+ $html[] = Html::openElement( 'div', array( 'class' =>
'mw-bookmanagerv2-nav-wrap' ) );
+ $html[] = Html::openElement( 'div', array( 'class' =>
'mw-bookmanagerv2-nav-constrain' ) );
+ $html[] = Html::openElement( 'div', array( 'class' =>
'mw-bookmanagerv2-nav-bar' ) );
+ $html[] = Html::openElement( 'a', array(
'class' => array(
'mw-bookmanagerv2-nav-icon',
- 'mw-bookmanagerv2-nav-data' )
+ 'mw-bookmanagerv2-nav-data' )
)
- )
- . Html::element( 'img', array(
+ );
+ $html[] = Html::element( 'img', array(
'class' => 'mw-bookmanagerv2-nav-data',
'src' => $imagePath .
'Info_sign_font_awesome.png'
- ), '' )
- . Html::closeElement( 'a' )
- . Html::openElement( 'a', array(
+ ), '' );
+ $html[] = Html::closeElement( 'a' );
+ $html[] = Html::openElement( 'a', array(
'class' => array(
'mw-bookmanagerv2-nav-icon',
'mw-bookmanagerv2-nav-toc' )
)
- )
- . Html::element( 'img', array(
+ );
+ $html[] = Html::element( 'img', array(
'class' => 'mw-bookmanagerv2-nav-toc',
'src' => $imagePath . 'Ul_font_awesome.png'
- ), '' )
- . Html::closeElement( 'a' )
- . Html::openElement( 'a', array(
- 'class' => 'mw-bookmanagerv2-nav-prev',
- 'href' => $prev->link )
- )
- . Html::element( 'img', array(
- 'class' => 'mw-bookmanagerv2-nav-prev',
- 'src' => $imagePath .
'Angle_left_font_awesome.png'
- ), '' )
- . $prev->title
- . Html::closeElement( 'a' )
- . Html::openElement( 'a', array(
- 'class' => 'mw-bookmanagerv2-nav-next',
- 'href' => $next->link )
- )
- . $next->title
- . Html::element( 'img', array(
- 'class' => 'mw-bookmanagerv2-nav-next',
- 'src' => $imagePath .
'Angle_right_font_awesome.png'
- ), '' )
- . Html::closeElement( 'a' )
- . Html::closeElement( 'div' )
- . Html::rawElement( 'div', array(
+ ), '' );
+ $html[] = Html::closeElement( 'a' );
+ if ( $prev ) {
+ $linkContents = array();
+ $linkContents[] = Html::element( 'img', array(
+ 'class' => 'mw-bookmanagerv2-nav-prev',
+ 'src' => $imagePath .
'Angle_left_font_awesome.png'
+ ), '' );
+ $linkContents[] = $prev->title;
+ $html[] = Linker::link(
+ Title::newFromText( $prev->link ),
+ implode( $linkContents ),
+ array( 'class' => 'mw-bookmanagerv2-nav-prev' )
+ );
+ }
+ if ( $next ) {
+ $linkContents = array();
+ $linkContents[] = $next->title;
+ $linkContents[] = Html::element( 'img', array(
+ 'class' => 'mw-bookmanagerv2-nav-next',
+ 'src' => $imagePath .
'Angle_right_font_awesome.png'
+ ), '' );
+ $html[] = Linker::link(
+ Title::newFromText( $next->link ),
+ implode( $linkContents ),
+ array( 'class' => 'mw-bookmanagerv2-nav-next' )
+ );
+ }
+ $html[] = Html::closeElement( 'div' );
+ $html[] = Html::rawElement( 'div', array(
'class' => array(
'mw-bookmanagerv2-nav-dropdown',
'mw-bookmanagerv2-nav-data' )
),
$metadata
- )
- . Html::rawElement( 'div', array(
+ );
+ $html[] = Html::rawElement( 'div', array(
'class' => array(
'mw-bookmanagerv2-nav-dropdown',
'mw-bookmanagerv2-nav-toc' )
),
$chapterList
- )
- . Html::closeElement( 'div' )
- . Html::closeElement( 'div' );
-
- $out->prependHTML( $html );
+ );
+ $html[] = Html::closeElement( 'div' );
+ $html[] = Html::closeElement( 'div' );
+ return implode( $html );
}
+ /**
+ * Pulls the text from an indicated page, decodes it as JSON.
+ *
+ * @param Title $title Title of the page from which the JSON is pulled
+ * @return object JSON object
+ */
+ public static function getJson( Title $title ) {
+ if ( !$title->exists() ) {
+ return false;
+ }
+ $jsonPage = WikiPage::factory( $title );
+ return json_decode( $jsonPage->getText( Revision::FOR_PUBLIC )
);
+ }
+
+ /**
+ * Creates a list item element with a comma-separated list of the array
values
+ *
+ * @param string $key Name of the JSON property
+ * @param array $array Array of strings
+ * @return string HTML list item element
+ */
+ public static function addArray( $key, $array ) {
+ global $wgContLang;
+ $output = Html::element( 'li', array(),
+ wfMessage( 'bookmanagerv2-' . $key )
+ ->numParams( count( $array ) )
+ ->params( $wgContLang->commaList( $array ) )
+ ->text() );
+ return $output;
+ }
+
+ /**
+ * Creates a list item element with a string
+ *
+ * @param string $key Name of the JSON property
+ * @param string $string Name of the string value
+ * @return string HTML list item element
+ */
+ public static function addString( $key, $string ) {
+ $output = Html::element( 'li', array(),
+ wfMessage( 'bookmanagerv2-' . $key, $string )->text() );
+ return $output;
+ }
+
+ /**
+ * Creates a list item element with a date.
+ *
+ * @param int|null $year Year
+ * @param int|null $month Month
+ * @param int|null $day Day
+ * @return string HTML list item element
+ */
+ public static function addDate( $year, $month, $day ) {
+ //TODO: This needs to be localized.
+ $output = array();
+ $output[] = Html::openElement( 'li', array() );
+ if ( $day && !$month ) {
+ //Having a day without a month doesn't make much sense
+ $date = $year;
+ } else {
+ $date = array();
+ $date[] = $day ? $day . "/" : "";
+ $date[] = $month ? $month . "/" : "";
+ $date[] = $year ? $year : "";
+ $date = implode( $date );
+ }
+ $output[] = wfMessage( 'bookmanagerv2-publication-date',
+ $date )->text();
+ $output[] = Html::closeElement( 'li' );
+ return implode( $output );
+ }
+
+ /**
+ * Generates HTML for the chapter list. All pages except the current one
+ * will be linked.
+ *
+ * @param object $sections Sections property of the JSON
+ * @param string $currentPageTitle Title of the page that's being viewed
+ * @return string HTML ordered list element
+ */
+ public static function formatChapterList( $sections, $currentPageTitle
) {
+ $html = array();
+ $html[] = Html::openElement( 'ol', array() );
+ foreach ( $sections as $key => $val ) {
+ if ( $val->link !== $currentPageTitle ) {
+ $html[] = Html::openElement( 'li', array() );
+ $html[] = Linker::link(
+ Title::newFromText( $val->link
),
+ $val->name
+ );
+ $html[] = Html::closeElement( 'li' );
+ } else {
+ $html[] = Html::element( 'li', array(),
$val->name );
+ }
+ }
+ $html[] = Html::closeElement( 'ol' );
+ return implode( $html );
+ }
+
+ /**
+ * Generates HTML for the metadata list.
+ *
+ * @param object $jsonBook JSON representation of the book
+ * @return string HTML unordered list element
+ */
+ public static function formatMetadata( $jsonBook ) {
+ $metadata = array();
+ $metadata[] = Html::openElement( 'ul', array() );
+ $metadata[] = Html::openElement( 'li', array() );
+ $metadata[] = wfMessage( 'bookmanagerv2-title',
+ $jsonBook->title)->text();
+ $metadata[] = Html::closeElement( 'li' );
+ if ( isset( $jsonBook->alternate_titles ) ) {
+ $metadata[] = self::addArray( "alternate-titles",
+ $jsonBook->alternate_titles );
+ }
+ if ( isset( $jsonBook->authors ) ) {
+ $metadata[] = self::addArray( "authors",
$jsonBook->authors );
+ }
+ if ( isset( $jsonBook->translators ) ) {
+ $metadata[] = self::addArray( "translators",
+ $jsonBook->translators );
+ }
+ if ( isset( $jsonBook->editors ) ) {
+ $metadata[] = self::addArray( "editors",
$jsonBook->editors );
+ }
+ if ( isset( $jsonBook->illustrators ) ) {
+ $metadata[] = self::addArray( "illustrators",
+ $jsonBook->illustrators );
+ }
+ if ( isset( $jsonBook->subtitle ) ) {
+ $metadata[] = self::addString( "subtitle",
$jsonBook->subtitle );
+ }
+ if ( isset( $jsonBook->series_title ) ) {
+ $metadata[] = self::addString( "series-title",
+ $jsonBook->series_title );
+ }
+ if ( isset( $jsonBook->volume ) ) {
+ $metadata[] = self::addString( "volume",
+ (string)$jsonBook->volume );
+ }
+ if ( isset( $jsonBook->edition ) ) {
+ $metadata[] = self::addString( "edition",
+ (string)$jsonBook->edition );
+ }
+ if ( isset( $jsonBook->publisher ) ) {
+ $metadata[] = self::addString( "publisher",
$jsonBook->publisher );
+ }
+ if ( isset( $jsonBook->publication_city ) ) {
+ $metadata[] = self::addString( "publication-city",
+ $jsonBook->publication_city );
+ }
+ if ( isset( $jsonBook->publication_year ) ) {
+ $year = isset( $jsonBook->publication_year ) ?
+ $jsonBook->publication_year : null;
+ $month = isset( $jsonBook->publication_month ) ?
+ $jsonBook->publication_month : null;
+ $day = isset( $jsonBook->publication_day ) ?
+ $jsonBook->publication_day : null;
+ $metadata[] = self::addDate( $year, $month, $day );
+ }
+ if ( isset( $jsonBook->printer ) ) {
+ $metadata[] = self::addString( "printer",
$jsonBook->printer );
+ }
+ if ( isset( $jsonBook->language ) ) {
+ //TODO: Transform the language code to the correct
long-form language
+ $metadata[] = self::addString( "language",
$jsonBook->language );
+ }
+ if ( isset( $jsonBook->description ) ) {
+ $metadata[] = self::addString( "description",
+ $jsonBook->description );
+ }
+ if ( isset( $jsonBook->isbn ) ) {
+ $metadata[] = self::addString( "isbn", $jsonBook->isbn
);
+ }
+ if ( isset( $jsonBook->lccn ) ) {
+ $metadata[] = self::addString( "lccn", $jsonBook->lccn
);
+ }
+ if ( isset( $jsonBook->oclc ) ) {
+ $metadata[] = self::addString( "oclc", $jsonBook->oclc
);
+ }
+ $metadata[] = Html::closeElement( 'ul' );
+
+ return implode( $metadata );
+ }
+
+ /**
+ * Adds the navigation bar if the page is in the mainspace, and if it
contains
+ * a category of the format [[Category:Book:Book Title]], where
+ * [[Book:Book Title]] is an existing page that contains a valid JSON
+ * block.
+ */
public static function onBeforePageDisplay( OutputPage &$out, Skin
&$skin ) {
// Check that the navigation bar is only added to mainspace
pages.
- if ( $out->getTitle()->getNamespace() == NS_MAIN ) {
- if ( $out->getRevisionId() != null ) {
- $out->addModules( "ext.BookManagerv2" );
- $prev = (object) array( "link" => "/prev.html",
"title" => "Previous" );
- $next = (object) array( "link" => "/next.html",
"title" => "Next" );
- $chapterList = Html::element( 'p', array(),
'Chapter 1' )
- . Html::element( 'p', array(), 'Chapter
2' )
- . Html::element( 'p', array(), 'Chapter
3' );
- $metadata = Html::openElement( 'p', array() )
- . 'Title: '
- . Html::element( 'span', array( 'class'
=> 'title' ), 'Title' )
- . Html::closeElement( 'p' )
- . Html::element( 'p', array(), 'Author:
Author' );
- self::readingInterfaceUX( $out, $prev, $next,
$chapterList, $metadata );
+ if ( $out->getTitle()->getNamespace() === NS_MAIN ) {
+ if ( $out->getRevisionId() !== null ) {
+ global $wgContLang;
+ $categories = $out->getCategories();
+ $namespace = $wgContLang->convertNamespace(
NS_BOOK ) . ":";
+ foreach ( $categories as $cat ) {
+ if ( substr( $cat, 0,
strlen($namespace) ) === $namespace ) {
+ $jsonPageTitle =
Title::newFromText( $cat );
+ $jsonBook = self::getJson(
$jsonPageTitle );
+ if ( $jsonBook ) {
+ $out->addModules(
"ext.BookManagerv2" );
+ $currentPageTitle =
$out->getTitle()->getText();
+ $prev = (object)
array();
+ $next = (object)
array();
+
+ //Get the previous/next
pages
+ foreach (
$jsonBook->sections as $key => $val ) {
+ if ( $val->link
=== $currentPageTitle ) {
+ if (
$key !== 0 ) {
+
$prev->title =
+
$jsonBook->sections[ $key - 1 ]->name;
+
$prev->link =
+
$jsonBook->sections[ $key - 1 ]->link;
+ } else {
+
$prev = null;
+ }
+ if (
$key !== count( $jsonBook->sections ) ) {
+
$next->title =
+
$jsonBook->sections[ $key + 1 ]->name;
+
$next->link =
+
$jsonBook->sections[ $key + 1 ]->link;
+ } else {
+
$next = null;
+ }
+ break;
+ }
+ }
+
+ $chapterList =
self::formatChapterList(
+
$jsonBook->sections, $currentPageTitle );
+ $metadata =
self::formatMetadata( $jsonBook );
+
+ $navbar =
self::readingInterfaceUX( $prev, $next,
+ $chapterList,
$metadata );
+ $out->prependHtml(
$navbar );
+ return true;
+ }
+ }
+ }
}
}
return true;
}
-
}
diff --git a/BookManagerv2.i18n.php b/BookManagerv2.i18n.php
index 226724e..454b7a2 100644
--- a/BookManagerv2.i18n.php
+++ b/BookManagerv2.i18n.php
@@ -15,6 +15,28 @@
$messages['en'] = array(
'bookmanagerv2-desc' => 'Adds functionality to enter and store book
metadata and structure',
'bookmanagerv2-invalid-json' => 'Invalid JSON',
+ 'bookmanagerv2-title' => 'Title: $1',
+ 'bookmanagerv2-alternate-titles' => '{{PLURAL:$1|Alternate
title|Alternate titles}}: $2',
+ 'bookmanagerv2-authors' => '{{PLURAL:$1|Author|Authors}}: $2',
+ 'bookmanagerv2-translators' => '{{PLURAL:$1|Translator|Translators}}:
$2',
+ 'bookmanagerv2-editors' => '{{PLURAL:$1|Editor|Editors}}: $2',
+ 'bookmanagerv2-illustrators' =>
'{{PLURAL:$1|Illustrator|Illustrators}}: $2',
+ 'bookmanagerv2-subtitle' => 'Subtitle: $1',
+ 'bookmanagerv2-series-title' => 'Series title: $1',
+ 'bookmanagerv2-volume' => 'Volume: $1',
+ 'bookmanagerv2-edition' => 'Edition: $1',
+ 'bookmanagerv2-publisher' => 'Publisher: $1',
+ 'bookmanagerv2-printer' => 'Printer: $1',
+ 'bookmanagerv2-publication-date' => 'Publication date: $1',
+ 'bookmanagerv2-publication-city' => 'Publication city: $1',
+ 'bookmanagerv2-language' => 'Language: $1',
+ 'bookmanagerv2-description' => 'Description: $1',
+ 'bookmanagerv2-source' => 'Source: $1',
+ 'bookmanagerv2-permission' => 'Permission: $1',
+ 'bookmanagerv2-other-versions' => '{{PLURAL:$1|Other version|Other
versions}}: $2',
+ 'bookmanagerv2-isbn' => 'ISBN: $1',
+ 'bookmanagerv2-lccn' => 'LCCN: $1',
+ 'bookmanagerv2-oclc' => 'OCLC: $1',
);
/** Message documentation (Message documentation)
@@ -25,6 +47,28 @@
'bookmanagerv2-desc' =>
'{{desc|name=BookManagerv2|url=http://www.mediawiki.org/wiki/Extension:BookManagerv2}}',
'bookmanagerv2-invalid-json' => 'Error message shown when an editor
tries to save an invalid JSON block.
{{Identical|Invalid JSON}}',
+ 'bookmanagerv2-title' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown. ',
+ 'bookmanagerv2-alternate-titles' => 'Label in the navigation bar
metadata dropdown. See [[File:BookManagerv2 navigation bar metadata
dropdown.png]] for an example of this dropdown. $1 is the length of the array
of titles',
+ 'bookmanagerv2-authors' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown. $1 is the length of the array of authors',
+ 'bookmanagerv2-translators' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown. $1 is the length of the array of translators',
+ 'bookmanagerv2-editors' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown. $1 is the length of the array of editors',
+ 'bookmanagerv2-illustrators' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown. $1 is the length of the array of illustrators',
+ 'bookmanagerv2-subtitle' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-series-title' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-volume' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-edition' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-publisher' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-printer' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-publication-date' => 'Label in the navigation bar
metadata dropdown. See [[File:BookManagerv2 navigation bar metadata
dropdown.png]] for an example of this dropdown. The value following may be just
a year, a month and a year, or a year, month, and day.',
+ 'bookmanagerv2-publication-city' => 'Label in the navigation bar
metadata dropdown. See [[File:BookManagerv2 navigation bar metadata
dropdown.png]] for an example of this dropdown',
+ 'bookmanagerv2-language' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-description' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-source' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-permission' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-other-versions' => 'Label in the navigation bar metadata
dropdown. See [[File:BookManagerv2 navigation bar metadata dropdown.png]] for
an example of this dropdown',
+ 'bookmanagerv2-isbn' => 'Label for the International Standard Book
Number, in the navigation bar metadata dropdown. See [[File:BookManagerv2
navigation bar metadata dropdown.png]] for an example of this dropdown',
+ 'bookmanagerv2-lccn' => 'Label for the Library of Congress Control
Number, in the navigation bar metadata dropdown. See [[File:BookManagerv2
navigation bar metadata dropdown.png]] for an example of this dropdown',
+ 'bookmanagerv2-oclc' => 'Label for the Online Computer Library Center,
in the navigation bar metadata dropdown. See [[File:BookManagerv2 navigation
bar metadata dropdown.png]] for an example of this dropdown',
);
/** German (Deutsch)
--
To view, visit https://gerrit.wikimedia.org/r/73150
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I9c2d77ce649c678ae34343032ef68b2b673dc92e
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/BookManagerv2
Gerrit-Branch: master
Gerrit-Owner: Mollywhite <[email protected]>
Gerrit-Reviewer: Helder.wiki <[email protected]>
Gerrit-Reviewer: Mollywhite <[email protected]>
Gerrit-Reviewer: Mwalker <[email protected]>
Gerrit-Reviewer: Nikerabbit <[email protected]>
Gerrit-Reviewer: Raylton P. Sousa <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits