From ccbef54c7c23657c621cd9a65ed46f5f1f3cac40 Mon Sep 17 00:00:00 2001 From: Giuseppe Di Terlizzi Date: Wed, 11 Nov 2015 23:45:46 +0100 Subject: [PATCH] Added helper for thirt-party plugin or template and added initial support for Dublin Core Metadata. --- action.php | 170 +++++++++--------------------------- conf/default.php | 2 +- conf/metadata.php | 1 + helper.php | 199 +++++++++++++++++++++++++++++++++++++++++++ lang/en/settings.php | 3 +- plugin.info.txt | 2 +- 6 files changed, 243 insertions(+), 134 deletions(-) create mode 100644 helper.php diff --git a/action.php b/action.php index acbd57b..99cfc99 100644 --- a/action.php +++ b/action.php @@ -36,8 +36,13 @@ class action_plugin_semantic extends DokuWiki_Action_Plugin { $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'meta_author'); } + if ($this->getConf('useDublinCore')) { + $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'meta_dublin_core'); + } + } + /** * JSON-LD Event handler * @@ -45,100 +50,9 @@ class action_plugin_semantic extends DokuWiki_Action_Plugin { */ public function json_ld(Doku_Event &$event, $param) { - global $INFO; - global $ID; + $helper = $this->loadHelper('semantic'); - if ((bool) preg_match('/'.$this->getConf('excludedPages').'/', $ID)) { - return false; - } - - if (! $INFO['perm']) { - return false; - } - - global $license; - global $auth; - global $conf; - - $meta = $INFO['meta']; - - if (isset($meta['semantic']['enabled']) && ! $meta['semantic']['enabled']) { - return false; - } - - if (isset($meta['date']) && $meta['date'] !== '') { - - $type = ((isset($meta['semantic']['schema.org']['type'])) - ? $meta['semantic']['schema.org']['type'] - : $this->getConf('defaultSchemaOrgType')); - $user_data = $auth->getUserData($meta['user']); - $license_url = @$license[$conf['license']]['url']; - $page_url = wl($ID, '', true); - $image_url = (($meta['relation']['firstimage']) ? ml($meta['relation']['firstimage'], '', true, '&', true) : null); - $description = trim(ltrim($meta['description']['abstract'], @$meta['title'])); - $created = date(DATE_W3C, $meta['date']['created']); - $modified = date(DATE_W3C, $meta['date']['modified']); - - $json_ld = array( - '@context' => 'http://schema.org', - '@type' => $type, - 'headline' => @$meta['title'], - 'name' => @$meta['title'], - 'image' => array($image_url), - 'datePublished' => $created, - 'dateCreated' => $created, - 'dateModified' => $modified, - 'description' => $description, - 'license' => $license_url, - 'url' => $page_url, - ); - - if (isset($meta['creator']) && $meta['creator'] !== '') { - - $json_ld['creator'] = array( - '@context' => 'http://schema.org', - '@type' => 'Person', - 'name' => $meta['creator'], - 'email' => $user_data['mail'] - ); - - if (isset($meta['contributor'])) { - foreach ($meta['contributor'] as $uid => $fullname) { - $contributor_data = $auth->getUserData($uid); - $json_ld['contributor'][] = array( - '@context' => 'http://schema.org', - '@type' => 'Person', - 'name' => $fullname, - 'email' => $contributor_data['mail'] - ); - } - } - - } - - if (isset($meta['relation']['references'])) { - - $json_ld_webpage = array( - '@context' => 'http://schema.org', - '@type' => 'WebPage' - ); - - foreach ($meta['relation']['references'] as $page => $status) { - if ($status) { - $json_ld_webpage['relatedLink'][] = wl($page, '', true); - } - } - - if (isset($json_ld_webpage['relatedLink'])) { - - $event->data["script"][] = array ( - "type" => "application/ld+json", - "_data" => json_encode($json_ld_webpage), - ); - - } - - } + if ($json_ld = $helper->getStructuredData()) { $event->data["script"][] = array ( "type" => "application/ld+json", @@ -147,31 +61,23 @@ class action_plugin_semantic extends DokuWiki_Action_Plugin { } + if ($json_ld_relations = $helper->getBacklinks()) { + $event->data["script"][] = array ( + "type" => "application/ld+json", + "_data" => json_encode($json_ld_relations), + ); + } + } public function meta_description(Doku_Event &$event, $params) { - global $INFO; - global $ID; + $helper = $this->loadHelper('semantic'); - if ((bool) preg_match_all('/'.$this->getConf('excludedPages').'/', $ID)) { - return false; - } + if ($description = $helper->getDescription()) { - if (! $INFO['perm']) { - return false; - } - - $meta = $INFO['meta']; - - if (isset($meta['semantic']['enabled']) && ! $meta['semantic']['enabled']) { - return false; - } - - if (isset($meta['date']) && $meta['date'] !== '') { - - $description = str_replace("\n", ' ', trim(ltrim($meta['description']['abstract'], @$meta['title']))); + $description = str_replace("\n", ' ', $description); $event->data['meta'][] = array( 'name' => 'description', @@ -185,31 +91,33 @@ class action_plugin_semantic extends DokuWiki_Action_Plugin { public function meta_author(Doku_Event &$event, $params) { - global $INFO; - global $ID; + $helper = $this->loadHelper('semantic'); - if ((bool) preg_match_all('/'.$this->getConf('excludedPages').'/', $ID)) { - return false; - } - - if (! $INFO['perm']) { - return false; - } - - $meta = $INFO['meta']; - - if (isset($meta['semantic']['enabled']) && ! $meta['semantic']['enabled']) { - return false; - } - - if ((isset($meta['date']) && $meta['date'] !== '')) { - - $meta = $INFO['meta']; + if ($author = $helper->getAuthor()) { $event->data['meta'][] = array( 'name' => 'author', - 'content' => $meta['creator'], + 'content' => $author, ); + + } + + } + + + public function meta_dublin_core(Doku_Event &$event, $params) { + + $helper = $this->loadHelper('semantic'); + + foreach ($helper->getDublinCore() as $name => $content) { + + if (! $content) continue; + + $event->data['meta'][] = array( + 'name' => $name, + 'content' => $content, + ); + } } diff --git a/conf/default.php b/conf/default.php index b676ebf..7d81720 100644 --- a/conf/default.php +++ b/conf/default.php @@ -9,5 +9,5 @@ $conf['useJSONLD'] = 1; $conf['defaultSchemaOrgType'] = 'Article'; $conf['useMetaDescription'] = 1; $conf['useMetaAuthor'] = 1; +$conf['useDublinCore'] = 0; $conf['excludedPages'] = '(wiki|playground)'; - diff --git a/conf/metadata.php b/conf/metadata.php index b0a7ff3..0f64419 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -7,6 +7,7 @@ $meta['useMetaDescription'] = array('onoff'); $meta['useMetaAuthor'] = array('onoff'); +$meta['useDublinCore'] = array('onoff'); $meta['useJSONLD'] = array('onoff'); $meta['defaultSchemaOrgType'] = array('multichoice','_choices' => array('Article', 'NewsArticle', 'TechArticle', 'BlogPosting', 'Recipe')); $meta['excludedPages'] = array('regex'); diff --git a/helper.php b/helper.php new file mode 100644 index 0000000..57a9183 --- /dev/null +++ b/helper.php @@ -0,0 +1,199 @@ + + */ + +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +class helper_plugin_semantic extends DokuWiki_Plugin { + + private $meta = array(); + + public function __construct() { + $this->meta = $this->getMetadata(); + } + + private function getMetadata() { + + global $INFO; + global $ID; + global $license; + global $auth; + global $conf; + + if ((bool) preg_match('/'. trim($this->getConf('excludedPages')) .'/', $ID)) return false; + + if (! $INFO['perm']) return false; + + $this->meta = $INFO['meta']; + + if (isset($this->meta['semantic']['enabled']) && ! $this->meta['semantic']['enabled']) { + return false; + } + + if (! isset($this->meta['date']) || $this->meta['date'] == '') return false; + + return $this->meta; + + } + + public function getSchemaOrgType() { + return ((isset($this->meta['semantic']['schema.org']['type'])) + ? $this->meta['semantic']['schema.org']['type'] + : $this->getConf('defaultSchemaOrgType')); + } + + public function getFirstImageURL() { + return (($this->meta['relation']['firstimage']) ? ml($this->meta['relation']['firstimage'], '', true, '&', true) : null); + } + + public function getDescription() { + return trim(ltrim($this->meta['description']['abstract'], @$this->meta['title'])); + } + + public function getAuthor() { + return ($this->meta['creator'] ? $this->meta['creator'] : null); + } + + public function getAuthorID() { + return ($this->meta['user'] ? $this->meta['user'] : null); + } + + public function getTitle() { + return ($this->meta['title'] ? $this->meta['title'] : null); + } + + public function getCreatedDate() { + return $this->meta['date']['created']; + } + + public function getModifiedDate() { + return $this->meta['date']['modified']; + } + + public function getLicense() { + global $license; + global $conf; + return @$license[$conf['license']]; + } + + /** + * Return JSON-LD structured data in according of selected Schema.org type + * + * @return array + */ + public function getStructuredData() { + + global $INFO; + global $ID; + global $auth; + global $conf; + + if (! count($this->meta)) return false; + + $license = $this->getLicense(); + $type = $this->getSchemaOrgType(); + $user_data = $auth->getUserData($this->getAuthorID()); + $license_url = $license['url']; + $page_url = wl($ID, '', true); + $image_url = $this->getFirstImageURL(); + $description = $this->getDescription(); + $created = date(DATE_W3C, $this->getCreatedDate()); + $modified = date(DATE_W3C, $this->getModifiedDate()); + + $json_ld = array( + '@context' => 'http://schema.org', + '@type' => $type, + 'headline' => @$this->meta['title'], + 'name' => @$this->meta['title'], + 'image' => array($image_url), + 'datePublished' => $created, + 'dateCreated' => $created, + 'dateModified' => $modified, + 'description' => $description, + 'license' => $license_url, + 'url' => $page_url, + ); + + if ($author = $this->getAuthor()) { + + $json_ld['creator'] = array( + '@context' => 'http://schema.org', + '@type' => 'Person', + 'name' => $author, + 'email' => $user_data['mail'] + ); + + if (isset($this->meta['contributor'])) { + foreach ($this->meta['contributor'] as $uid => $fullname) { + $contributor_data = $auth->getUserData($uid); + $json_ld['contributor'][] = array( + '@context' => 'http://schema.org', + '@type' => 'Person', + 'name' => $fullname, + 'email' => $contributor_data['mail'] + ); + } + } + + } + + return $json_ld; + + } + + public function getBacklinks() { + + global $ID; + + if (! $backlinks = ft_backlinks($ID)) return false; + + $json_ld_webpage = array( + '@context' => 'http://schema.org', + '@type' => 'WebPage' + ); + + foreach ($backlinks as $pageid) { + $json_ld_webpage['relatedLink'][] = wl($pageid, '', true); + } + + if (isset($json_ld_webpage['relatedLink'])) return $json_ld_webpage; + + } + + + public function getDublinCore() { + + global $conf; + global $ID; + + if (! $this->meta = $this->getMetadata()) return false; + + $license = $this->getLicense(); + $contributors = array(); + foreach ($this->meta['contributor'] as $uid => $fullname) { + $contributors[] = $fullname; + } + + $dublin_core = array( + 'DC.Title' => $this->getTitle(), + 'DC.Description' => str_replace("\n", ' ', $this->getDescription()), + 'DC.Publisher' => $this->getAuthor(), + 'DC.Contributors' => implode(', ', $contributors), + 'DC.Rights' => $license['name'], + 'DC.Language' => $conf['lang'], + 'DC.Created' => date(DATE_W3C, $this->getCreatedDate()), + 'DC.Modified' => date(DATE_W3C, $this->getModifiedDate()), + 'DC.Date' => date(DATE_W3C, $this->getCreatedDate()), + 'DC.Identifier' => "urn:$ID", + ); + + return $dublin_core; + + } + +} diff --git a/lang/en/settings.php b/lang/en/settings.php index f86bff2..1d37773 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -5,10 +5,11 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Giuseppe Di Terlizzi */ - + // for the configuration manager $lang['useMetaDescription'] = 'Add description meta tag'; $lang['useMetaAuthor'] = 'Add author meta tag'; +$lang['useDublinCore'] = 'Add Dublin Core metadata'; $lang['useJSONLD'] = 'Add JSON-LD'; $lang['defaultSchemaOrgType'] = 'Default Schema.org type for JSON-LD'; $lang['excludedPages'] = 'Excluded pages (insert a regex)'; diff --git a/plugin.info.txt b/plugin.info.txt index b0b2461..66bb4e8 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base semantic author Giuseppe Di Terlizzi email giuseppe.diterlizzi@gmail.com -date 2015-10-30 +date 2015-11-11 name Semantic Plugin desc Add Semantic Data in DokuWiki url http://www.dokuwiki.org/plugin:semantic