Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Book metadata support #3

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions Book.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php
teran marked this conversation as resolved.
Show resolved Hide resolved
/**
* GoogleRichCards
* Google Rich Cards metadata generator for Books
*
* PHP version 5.4
*
* @category Extension
* @package GoogleRichCards
* @author Igor Shishkin <me@teran.ru>
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File author should be here :-)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is already what is there, no?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you created the file so you're the author :)

* @license GPL http://www.gnu.org/licenses/gpl.html
* @link https://github.com/teran/mediawiki-GoogleRichCards
*/

namespace MediaWiki\Extension\GoogleRichCards;

use OutputPage;
use Parser;
use PPFrame;

if (!defined('MEDIAWIKI')) {
echo("This is a Mediawiki extension and doesn't provide standalone functionality\n");
die(1);
}

class Book {
/**
* @var static Book instance for Signleton pattern
*/
public static $instance;

/**
* Singleon pattern getter
*
* @return Book
*/
public static function getInstance() {
if(!isset(self::$instance)) {
self::$instance = new Book();
}

return self::$instance;
}

public function parse($text, $params = [], Parser $parser, PPFrame $frame) {
$o = array();
foreach($params as $k => $v) {
$o[$k] = $parser->recursiveTagParse($v, $frame);
}
return '<!-- BookData:'.json_encode($o).' -->';
}

public function render(OutputPage &$out) {
if($out->isArticle()) {
foreach($this->getData($out->mBodytext) as $book) {
$e = json_decode($book);

$book = array(
'@context' => 'http://schema.org',
'@type' => 'book',
'name' => $this->getMetadataField($e, 'name', 'name'),
'publisher' => $e->{'publisher'},
'numberOfPages' => $e->{'numberOfPages'},
'isbn' => $e->{'isbn'},
'bookEdition' => $e->{'bookEdition'},
'description' => $this->getMetadataField($e, 'description', 'description'),
'image' => $this->getRawURL($e->{'image'}),
);



if($e->{'author'}) {
$book['author'] = array(
'@type' => 'PerformingGroup',
'name' => $this->getMetadataField($e, 'author', 'author'),
);

if($e->{'offer'}) {
$book['offers'] = array(
'@type' => 'Offer',
'url' => $this->getRawURL($e->{'offerurl'}),
'price' => $this->getMetadataField($e, 'offerPrice', 'offerprice'),
'priceCurrency' => $this->getMetadataField($e, 'offerCurrency', 'offercurrency'),
'availability' => $this->getItemAvailability($e->{'offeravailability'}),
'validFrom' => $this->getMetadataField($e, 'validFrom', 'validfrom'),
);
}
}

$out->addHeadItem(
'GoogleRichCardsBook_'.$e->{'name'},
'<script type="application/ld+json">'.json_encode($book).'</script>'
);
}
}
}

private function getData($pageText) {
$matches = preg_match_all('/<!-- BookData:(\{(.*)\}) -->/m', $pageText, $extracted);

return $extracted[1];
}

private function getRawURL($htmlLink) {
$matches = preg_match_all('/((https?:\\/\\/)([a-z0-9\.\/_-]+))/i', $htmlLink, $extracted);

return $extracted[0][0];
}

private function getItemAvailability($value) {
switch ($value) {
case "Discontinued":
return "http://schema.org/Discontinued";
case "InStock":
return "http://schema.org/InStock";
case "InStoreOnly":
return "http://schema.org/InStoreOnly";
case "LimitedAvailability":
return "http://schema.org/LimitedAvailability";
case "OnlineOnly":
return "http://schema.org/OnlineOnly";
case "OutOfStock":
return "http://schema.org/OutOfStock";
case "PreOrder":
return "http://schema.org/PreOrder";
case "PreSale":
return "http://schema.org/PreSale";
case "SoldOut":
return "http://schema.org/SoldOut";
}
return "";
}

private function getMetadataField($obj, $field, $name) {
$value = $obj->{$name};
if ($value == '{{{'.$field.'}}}') {
return "";
}
return $value;
}
}

?>
19 changes: 17 additions & 2 deletions Hooks.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Hooks {
* @return bool
*/
public static function onBeforePageDisplay(OutputPage &$out, Skin &$skin) {
global $wgGoogleRichCardsAnnotateArticles, $wgGoogleRichCardsAnnotateEvents, $wgGoogleRichCardsAnnotateWebSite;
global $wgGoogleRichCardsAnnotateArticles, $wgGoogleRichCardsAnnotateEvents, $wgGoogleRichCardsAnnotateBooks, $wgGoogleRichCardsAnnotateWebSite;

if($wgGoogleRichCardsAnnotateArticles) {
$article = Article::getInstance();
Expand All @@ -38,6 +38,12 @@ public static function onBeforePageDisplay(OutputPage &$out, Skin &$skin) {
$event = Event::getInstance();
$event->render($out);
}

if($wgGoogleRichCardsAnnotateBooks) {
teran marked this conversation as resolved.
Show resolved Hide resolved
$book = Event::getInstance();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Book::getInstance()

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least it does not lead to a crash, but then, i obtain a event instead of a book…

$book->render($out);

}

if($wgGoogleRichCardsAnnotateWebSite) {
$website = WebSite::getInstance();
Expand All @@ -60,7 +66,16 @@ public static function onParserFirstCallInit(Parser &$parser) {
$event = Event::getInstance();
$parser->setHook('event', [$event, 'parse']);
}
}


/* public static function onParserFirstCallInit(Parser &$parser) {*/
global $wgGoogleRichCardsAnnotateBooks;

if($wgGoogleRichCardsAnnotateBooks) {
$book = Event::getInstance();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Book::getInstance();

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure of getting it: if I use
$book = Book::getInstance();
it crashes

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check out logs of your HTTP server, the reason should be there

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check out logs of your HTTP server, the reason should be there

Where in the log?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@giby probably right after HTTP request to mediawiki pages it should appear in error log(usually HTTP servers, both of nginx and apache/httpd writes two log files: access.log and error.log). Your error/exception traceback should be there.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my hosting provider proposes me
2018-11 : web - ftp - error - out
I cheacked "web" and "error" and nothing related to mediawiki…

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@giby probably your provider doesn't have logs verbose enough for that, give me some time to check it out.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made crach my wiki, and get a 504 error :(

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@giby So simply restore the extension :) I hope you used it right from git, so you could easily switch between exact commits.

Btw, for development I would like to suggest you to use Docker, which will bring you fast local development workflow no matter if you are using macOS or Windows. To deploy wiki+database for development it will take about 1 minute with that workflow.

PS. Development right on running project(i.e. production) is not such a good idea ;)

$parser->setHook('book', [$book, 'parse']);
}
}

}

Expand Down
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ $wgGoogleRichCardsAnnotateArticles = true;
// Enable annotations for events
$wgGoogleRichCardsAnnotateEvents = true;

// Enable annotations for books
$wgGoogleRichCardsAnnotateBooks = true;

// Enable WebSite annotations
$wgGoogleRichCardsAnnotateWebSite = true;
```
Expand All @@ -55,7 +58,22 @@ Performer: {{{performer}}}

Please note, you're free to update this template in order to setup events publishing in your own flavour

### Usage of Event template
### Template:Book
```

### Usage of book template
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this gonna be out of triple ticks


== Livre ==
=== {{{name}}} ===

{{{description}}}



auteur: {{{author}}}


<book name="{{{name}}}" place="{{{place}}}" description="{{{description}}}" postalCode="{{{postalCode}}}" locality="{{{locality}}}" region="{{{region}}}" country="{{{country}}}" author="{{{author}}}" streetaddress="{{{streetAddress}}}" offer="{{{offer}}}" offerURL="{{{offerURL}}}" offerPrice="{{{offerPrice}}}" offerCurrency="{{{offerCurrency}}}" offerAvailability="{{{offerAvailability}}}" validFrom="{{{validFrom}}}" image="{{{image}}} />

```
{{Event
Expand All @@ -78,3 +96,23 @@ Please note, you're free to update this template in order to setup events publis
|validFrom=2018-06-01T10:00+03:00
}}
```

### Usage of Event template
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Book template?:)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a detail, I'll correct when all will be ok :) I might have other things to add in ;)

```
{{Book
|name=La reconstruction de la ville de Valenciennes (1940-1959)
|place=Valenciennes
|description=Après l'incendie du 22 mai 1940, Valenciennes située en zone interdite est sous la tutelle de l'Autorité administrative allemande. André Muffang, Commissaire à la Reconstruction, désigne Valenciennes comme l'une des premières villes sinistrées à reconstruire. Le plan de reconstruction de la ville et l'aménagement de son agglomération est établi sous Vichy par l'éminent architecte-urbaniste Albert Laprade. Il est reconnu d'utilité publique le 24 juin 1943 et vise à consacrer la ville comme capitale du Hainaut afin d'en faire, à terme le centre d'un nouveau département. Ce plan ne sera pas remis en question après guerre.
|postalCode=000000
|locality=Valenciennes
|region=Haut de France
|country=Fr
|offerAvailability=InStock
|author=Jean-Marie Richez
|offerPrice=26
|offerCurrency=EUR
|offerURL=http://www.histoire-valenciennes-cahv.fr/index.php?title=La_reconstruction_de_la_ville_de_Valenciennes_(1940-1959)
|image=http://www.histoire-valenciennes-cahv.fr/Memoires/public/journals/1/cover_issue_60_fr_CA.jpg
|validFrom=2018-06-01T10:00+03:00
}}
```
1 change: 1 addition & 0 deletions extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"MediaWiki\\Extension\\GoogleRichCards\\Hooks": "Hooks.php",
"MediaWiki\\Extension\\GoogleRichCards\\Article": "Article.php",
"MediaWiki\\Extension\\GoogleRichCards\\Event": "Event.php",
"MediaWiki\\Extension\\GoogleRichCards\\Book": "Book.php",
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep code style while adding something

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see the difference with mine :(

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably about ident characters to use by your text editor. Please set it up according to the way file is formatted.

"MediaWiki\\Extension\\GoogleRichCards\\WebSite": "WebSite.php"
},
"Hooks": {
Expand Down