install plugin
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# v2.0.1
|
||||
## 07-07-2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Added check to include metadata saved prior to v2.0.0
|
||||
|
||||
1. [](#bugfix)
|
||||
* Updated date published/modified functionality to ensure output of valid timestamp
|
||||
|
||||
# v2.0.0
|
||||
## 23-06-2020
|
||||
|
||||
1. [](#improved)
|
||||
* Changed the way metadata is stored in frontmatter to capitalise on Grav page caching. **Important:** When upgrading from a previous version existing Aura metadata output will be disabled. You will not be required to re-enter any information, but you will need to actively re-save each page via the page editor to re-enable metadata output.
|
||||
|
||||
1. [](#new)
|
||||
* Metadata input moved from Options tab to Aura tab in page editor for central editing location and to enable overriding of individual meta tags
|
||||
|
||||
1. [](#new)
|
||||
* Added support for individual author per page via Aura Authors plugin
|
||||
|
||||
1. [](#bugfix)
|
||||
* Changed storage location of Organization logo so it will be retained after plugin updates
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed issue with URL extension appearing within page image URL
|
||||
|
||||
# v1.0.3
|
||||
## 29-02-2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Adjusted scope of autoloader so it will not interfere with other 'Aura' prefixed plugins
|
||||
|
||||
# v1.0.2
|
||||
## 09-02-2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Now appends to existing metadata rather than replacing
|
||||
|
||||
# v1.0.1
|
||||
## 06-09-2019
|
||||
|
||||
1. [](#improved)
|
||||
* Get language defined in page frontmatter with fallbacks to active language then default language
|
||||
1. [](#bugfix)
|
||||
* Adjusted JSON output to suit Grav versions > 1.5
|
||||
|
||||
# v1.0.0
|
||||
## 21-08-2019
|
||||
|
||||
1. [](#new)
|
||||
* ChangeLog started...
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Matt Mulhall
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Aura Plugin
|
||||
|
||||
The **Aura** Plugin for [Grav CMS](https://github.com/getgrav/grav) adds meta tags and structured data to your pages for visually appealing and informative search results and social media sharing.
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Minimal configuration required to automatically inject a wealth of structured/meta data into all pages of your site.
|
||||
* Supports the following standards and protocols:
|
||||
* [Schema.org](https://schema.org/) structured data ld+json code snippet as used by major search providers Google, Microsoft, Yahoo! and Yandex
|
||||
* [Open Graph](https://ogp.me/) meta tags as used by social platforms Facebook and Pinterest
|
||||
* [Twitter Card](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards.html) meta tags
|
||||
* [LinkedIn Article](https://www.linkedin.com/help/linkedin/answer/46687/making-your-website-shareable-on-linkedin?lang=en) meta tags
|
||||
|
||||
## Installation
|
||||
|
||||
### Admin Plugin
|
||||
|
||||
It is recommended to install Aura directly through the Admin Plugin by browsing to the `Plugins` tab and selecting `Add`.
|
||||
|
||||
**Important:** If upgrading from a version < 2.0.0 existing Aura metadata output will be disabled due to a change in the way the metadata is stored. You will not be required to re-enter any information, but you will need to actively re-save each page via the page editor to re-enable metadata output. The new method of saving metadata capitalises on Grav's inbuilt page caching for optimal site performance.
|
||||
|
||||
## Configuration
|
||||
|
||||
You can configure Aura via the Admin Plugin by browsing to `Plugins` and selecting `Aura`.
|
||||
|
||||
There are only two required fields to complete to get up and running: Organization Name and URL. However the more information you can provide, the richer your shared content will be.
|
||||
|
||||
## Usage
|
||||
|
||||
Global settings are configured at the plugin level as described above. These values are constant for each page of your site e.g. Oranization name, logo and social account details.
|
||||
|
||||
There is an additional configuration tab titled `Aura` available on each page in the page editor. This is where to set page specific information such as the meta description. Other than meta description, data required at a page level (URL, title etc.) will be automatically inferred from Grav's internal system settings.
|
||||
|
||||
Additional metadata can also be entered on this tab. For example to signal to web crawlers not to index the page, enter key: `robots` and value: `noindex,nofollow`.
|
||||
|
||||
Individual Aura generated meta tags can be overridden with the Additional Metadata input as well. For example to display a specific title when sharing on Twitter only, enter a custom value for the key `twitter:title`.
|
||||
|
||||
## Credits
|
||||
|
||||
Big thanks to [Yoast](https://yoast.com/) for sharing their wealth of knowledge on structured data and SEO.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
namespace Grav\Plugin;
|
||||
|
||||
use Grav\Common\Plugin;
|
||||
use Grav\Common\Page\Page;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Plugin\Aura\Aura;
|
||||
|
||||
|
||||
/**
|
||||
* Class AuraPlugin
|
||||
* @package Grav\Plugin
|
||||
*/
|
||||
class AuraPlugin extends Plugin
|
||||
{
|
||||
|
||||
/**
|
||||
* Gives the core a list of events the plugin wants to listen to
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
'onPluginsInitialized' => ['onPluginsInitialized', 0]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the plugin
|
||||
*/
|
||||
public function onPluginsInitialized()
|
||||
{
|
||||
|
||||
// Don't proceed if php ext-json is not available
|
||||
if (!function_exists('json_encode')) {
|
||||
return;
|
||||
}
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
if (Utils::startsWith($class, 'Grav\Plugin\Aura\\')) {
|
||||
require_once __DIR__ .'/classes/' . strtolower(basename(str_replace("\\", '/', $class))) . '.php';
|
||||
}
|
||||
});
|
||||
|
||||
// Admin only events
|
||||
if ($this->isAdmin()) {
|
||||
$this->enable([
|
||||
'onGetPageBlueprints' => ['onGetPageBlueprints', 0],
|
||||
'onAdminSave' => ['onAdminSave', 0],
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Frontend events
|
||||
$this->enable([
|
||||
'onPageInitialized' => ['onPageInitialized', 0]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend page blueprints with additional configuration options.
|
||||
*
|
||||
* @param Event $event
|
||||
*/
|
||||
public function onGetPageBlueprints($event)
|
||||
{
|
||||
$types = $event->types;
|
||||
$types->scanBlueprints('plugins://' . $this->name . '/blueprints');
|
||||
}
|
||||
|
||||
public function onAdminSave(Event $event)
|
||||
{
|
||||
// Don't proceed if Admin is not saving a Page
|
||||
if (!$event['object'] instanceof Page) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't proceed if required params not set
|
||||
$requiredParams = array(
|
||||
'org-name',
|
||||
'org-url',
|
||||
);
|
||||
foreach ($requiredParams as $param) {
|
||||
$key = 'plugins.aura.' . $param;
|
||||
if (!$this->grav['config']->get($key)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$page = $event['object'];
|
||||
$aura = new Aura($page);
|
||||
|
||||
// Meta Description
|
||||
if ($aura->webpage->description) {
|
||||
// Append description to page metadata
|
||||
$aura->webpage->metadata['description'] = array(
|
||||
'name' => 'description',
|
||||
'content' => htmlentities($aura->webpage->description),
|
||||
);
|
||||
}
|
||||
|
||||
// Open Graph
|
||||
if ($this->grav['config']->get('plugins.aura.output-og')) {
|
||||
$aura->generateOpenGraphMeta();
|
||||
}
|
||||
|
||||
// Twitter
|
||||
if ($this->grav['config']->get('plugins.aura.output-twitter')) {
|
||||
$aura->generateTwitterMeta();
|
||||
}
|
||||
|
||||
// LinkedIn
|
||||
if ($this->grav['config']->get('plugins.aura.output-linkedin')) {
|
||||
$aura->generateLinkedInMeta();
|
||||
}
|
||||
|
||||
// Generate Aura metadata
|
||||
$metadata = [];
|
||||
foreach ($aura->webpage->metadata as $tag) {
|
||||
if (array_key_exists('property', $tag)) {
|
||||
$metadata[$tag['property']] = $tag['content'];
|
||||
} else if (array_key_exists('name', $tag)) {
|
||||
$metadata[$tag['name']] = $tag['content'];
|
||||
}
|
||||
}
|
||||
|
||||
// Check for existing metadata that may have been set prior to installation of Aura v2.0.0.
|
||||
if (isset($page->header()->metadata) && is_array($page->header()->metadata)) {
|
||||
foreach ($page->header()->metadata as $key => $val) {
|
||||
$exists = false;
|
||||
if (array_key_exists($key, $metadata)) {
|
||||
$exists = true;
|
||||
} else {
|
||||
if (isset($page->header()->aura['metadata']) && is_array($page->header()->aura['metadata'])) {
|
||||
if (array_key_exists($key, $page->header()->aura['metadata'])) {
|
||||
$exists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$exists) {
|
||||
$metadata[$key] = $val;
|
||||
$page->header()->aura['metadata'] = array($key => $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$page->header()->metadata = array_merge($metadata, isset($page->header()->aura['metadata']) ? $page->header()->aura['metadata'] : []);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert meta tags and structured data to head of each page
|
||||
*
|
||||
* @param Event $e
|
||||
*/
|
||||
public function onPageInitialized()
|
||||
{
|
||||
// Structured Data
|
||||
if ($this->grav['config']->get('plugins.aura.output-sd')) {
|
||||
|
||||
// Don't proceed if required params not set
|
||||
$requiredParams = array(
|
||||
'org-name',
|
||||
'org-url',
|
||||
);
|
||||
foreach ($requiredParams as $param) {
|
||||
$key = 'plugins.aura.' . $param;
|
||||
if (!$this->grav['config']->get($key)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$page = $this->grav['page'];
|
||||
$assets = $this->grav['assets'];
|
||||
|
||||
$aura = new Aura($page);
|
||||
|
||||
// Generate structured data block
|
||||
$sd = $aura->generateStructuredData();
|
||||
// Drop into JS pipeline
|
||||
$type = array('type' => 'application/ld+json');
|
||||
if (version_compare(GRAV_VERSION, '1.6.0', '<')) {
|
||||
$type = 'application/ld+json';
|
||||
}
|
||||
$assets->addInlineJs($sd, null, null, $type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
enabled: true
|
||||
@@ -0,0 +1,137 @@
|
||||
name: Aura
|
||||
version: 2.0.1
|
||||
description: Automatically add meta tags and structured data to your pages for visually appealing and informative search results and social media sharing.
|
||||
icon: code
|
||||
author:
|
||||
name: Matt Mulhall
|
||||
email: matt@theskylab.net
|
||||
url: https://www.theskylab.net
|
||||
homepage: https://github.com/matt-j-m/grav-plugin-aura
|
||||
keywords: seo, structured data, open graph
|
||||
bugs: https://github.com/matt-j-m/grav-plugin-aura/issues
|
||||
license: MIT
|
||||
|
||||
form:
|
||||
validation: strict
|
||||
fields:
|
||||
enabled:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.PLUGIN_STATUS
|
||||
highlight: 1
|
||||
default: 0
|
||||
options:
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
validate:
|
||||
type: bool
|
||||
output-heading:
|
||||
type: section
|
||||
title: Output Options
|
||||
text: '<em>Enable any or all of the following options to include the relevant tags and metadata in each page.</em>'
|
||||
underline: true
|
||||
output-sd:
|
||||
type: toggle
|
||||
label: schema.org Structured Data (Google, Microsoft, Yahoo!, Yandex)
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
validate:
|
||||
type: bool
|
||||
output-og:
|
||||
type: toggle
|
||||
label: Open Graph (Facebook, Pinterest)
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
validate:
|
||||
type: bool
|
||||
output-twitter:
|
||||
type: toggle
|
||||
label: Twitter Card
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
validate:
|
||||
type: bool
|
||||
output-linkedin:
|
||||
type: toggle
|
||||
label: LinkedIn Article
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
validate:
|
||||
type: bool
|
||||
org-heading:
|
||||
type: section
|
||||
title: Organization Information
|
||||
underline: true
|
||||
org-name:
|
||||
type: text
|
||||
size: large
|
||||
label: Name
|
||||
validate:
|
||||
required: true
|
||||
org-url:
|
||||
type: text
|
||||
size: large
|
||||
label: URL
|
||||
validate:
|
||||
required: true
|
||||
org-logo:
|
||||
type: file
|
||||
size: large
|
||||
label: Logo (minimum 112x112px .jpg, .png or .gif format only)
|
||||
multiple: false
|
||||
destination: 'user/images'
|
||||
accept:
|
||||
- .jpg
|
||||
- .png
|
||||
- .gif
|
||||
org-facebook-url:
|
||||
type: text
|
||||
size: large
|
||||
label: Facebook URL
|
||||
placeholder: 'https://www.facebook.com/username'
|
||||
org-facebook-appid:
|
||||
type: text
|
||||
size: large
|
||||
label: Facebook App ID
|
||||
placeholder: '1234567890'
|
||||
org-twitter-user:
|
||||
type: text
|
||||
size: large
|
||||
label: Twitter Username
|
||||
placeholder: 'username'
|
||||
org-instagram-url:
|
||||
type: text
|
||||
size: large
|
||||
label: Instagram URL
|
||||
placeholder: 'https://www.instagram.com/username/'
|
||||
org-linkedin-url:
|
||||
type: text
|
||||
size: large
|
||||
label: LinkedIn URL
|
||||
placeholder: 'https://www.linkedin.com/company/company-name/'
|
||||
org-pinterest-url:
|
||||
type: text
|
||||
size: large
|
||||
label: Pinterest URL
|
||||
placeholder: 'https://www.pinterest.com/username/'
|
||||
org-youtube-url:
|
||||
type: text
|
||||
size: large
|
||||
label: YouTube URL
|
||||
placeholder: 'https://www.youtube.com/username'
|
||||
org-wikipedia-url:
|
||||
type: text
|
||||
size: large
|
||||
label: Wikipedia URL
|
||||
placeholder: "https://en.wikipedia.org/wiki/Company"
|
||||
@@ -0,0 +1,61 @@
|
||||
title: Aura
|
||||
'@extends':
|
||||
type: default
|
||||
context: blueprints://pages
|
||||
|
||||
form:
|
||||
fields:
|
||||
tabs:
|
||||
type: tabs
|
||||
active: 1
|
||||
|
||||
fields:
|
||||
|
||||
options:
|
||||
type: tab
|
||||
title: PLUGIN_ADMIN.OPTIONS
|
||||
|
||||
fields:
|
||||
publishing:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.PUBLISHING
|
||||
underline: true
|
||||
|
||||
fields:
|
||||
header.metadata:
|
||||
unset@: true
|
||||
|
||||
aura:
|
||||
type: tab
|
||||
title: Aura
|
||||
|
||||
fields:
|
||||
|
||||
header.aura.pagetype:
|
||||
type: select
|
||||
label: Page Type
|
||||
size: medium
|
||||
options:
|
||||
website: Website (default)
|
||||
article: Article
|
||||
validate:
|
||||
required: true
|
||||
|
||||
header.aura.description:
|
||||
type: text
|
||||
size: long
|
||||
label: 'Page Description'
|
||||
description: 'Recommended length 140-160 characters.'
|
||||
|
||||
header.aura.image:
|
||||
type: filepicker
|
||||
label: Preview Image
|
||||
preview_images: true
|
||||
description: 'Recommended size 1920x1080px in .jpg, .png or .gif format only. If not specified, will default to the first image found in the page''s folder.'
|
||||
|
||||
header.aura.metadata:
|
||||
toggleable: true
|
||||
type: array
|
||||
label: Additional Metadata
|
||||
placeholder_key: PLUGIN_ADMIN.METADATA_KEY
|
||||
placeholder_value: PLUGIN_ADMIN.METADATA_VALUE
|
||||
@@ -0,0 +1,443 @@
|
||||
<?php
|
||||
namespace Grav\Plugin\Aura;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Plugin\AuraAuthorsPlugin;
|
||||
|
||||
class Aura
|
||||
{
|
||||
private $org;
|
||||
private $website;
|
||||
public $webpage;
|
||||
private $person;
|
||||
private $grav;
|
||||
|
||||
private $otherPresence = array(
|
||||
'facebook-url',
|
||||
'instagram-url',
|
||||
'linkedin-url',
|
||||
'pinterest-url',
|
||||
'youtube-url',
|
||||
'wikipedia-url',
|
||||
'website-url',
|
||||
);
|
||||
|
||||
/**
|
||||
* Initializes Aura variables for the page
|
||||
*
|
||||
* @param object $page
|
||||
*
|
||||
*/
|
||||
public function __construct(Page $page)
|
||||
{
|
||||
|
||||
$this->grav = $cache = Grav::instance();
|
||||
|
||||
/*
|
||||
* Organization
|
||||
*/
|
||||
$this->org = new Organization();
|
||||
|
||||
$this->org->url = (string)$this->grav['config']->get('plugins.aura.org-url');
|
||||
$this->org->id = $this->org->url . '#organization';
|
||||
$this->org->name = $this->grav['config']->get('plugins.aura.org-name');
|
||||
|
||||
// Org SameAs
|
||||
$sameAs = array();
|
||||
foreach ($this->otherPresence as $platform) {
|
||||
$key = 'plugins.aura.org-' . $platform;
|
||||
if ($this->grav['config']->get($key)) {
|
||||
$sameAs[] = $this->grav['config']->get($key);
|
||||
}
|
||||
}
|
||||
$key = 'plugins.aura.' . 'org-twitter-user';
|
||||
if ($this->grav['config']->get($key)) {
|
||||
$sameAs[] = 'https://twitter.com/' . $this->grav['config']->get($key);
|
||||
}
|
||||
if (!empty($sameAs)) {
|
||||
$this->org->sameAs = $sameAs;
|
||||
}
|
||||
|
||||
// Org Logo
|
||||
if ($this->grav['config']->get('plugins.aura.org-logo')) {
|
||||
$imageArray = $this->grav['config']->get('plugins.aura.org-logo');
|
||||
$firstImage = reset($imageArray);
|
||||
$imagePath = ROOT_DIR . $firstImage['path'];
|
||||
if (file_exists($imagePath)) {
|
||||
$size = getimagesize($imagePath);
|
||||
$this->org->logo = new Image();
|
||||
$this->org->logo->url = $this->grav['base_url_absolute'] . '/' . $firstImage['path'];
|
||||
$this->org->logo->id = $this->org->url . '#logo';
|
||||
$this->org->logo->width = $size[0];
|
||||
$this->org->logo->height = $size[1];
|
||||
$this->org->logo->caption = $this->org->name;
|
||||
$this->org->logo->type = $size['mime'];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Website
|
||||
*/
|
||||
$this->website = new WebSite;
|
||||
|
||||
$this->website->url = $this->grav['base_url_absolute'];
|
||||
$this->website->id = $this->website->url . '#website';
|
||||
$this->website->name = $this->grav['config']->get('site.title');
|
||||
|
||||
|
||||
/*
|
||||
* Webpage
|
||||
*/
|
||||
$this->webpage = new WebPage;
|
||||
|
||||
$this->webpage->url = $page->url(true);
|
||||
$this->webpage->id = $this->webpage->url . '#webpage';
|
||||
$this->webpage->title = $page->title() . ' | ' . $this->grav['config']->get('site.title');
|
||||
$header = $page->header();
|
||||
if ((isset($header->aura['description'])) && ($header->aura['description'] != '')) {
|
||||
$this->webpage->description = (string)$header->aura['description'];
|
||||
}
|
||||
if ((isset($header->language)) and ($header->language != '')) {
|
||||
$this->webpage->language = $header->language;
|
||||
} else {
|
||||
$this->webpage->language = $this->grav['language']->getActive();
|
||||
if (!$this->webpage->language) {
|
||||
$this->webpage->language = $this->grav['config']->get('site.default_lang');
|
||||
}
|
||||
}
|
||||
|
||||
$datePublishedRaw = time();
|
||||
if ($page->publishDate()) {
|
||||
$datePublishedRaw = $page->publishDate();
|
||||
} else if ($page->date()) {
|
||||
$datePublishedRaw = $page->date();
|
||||
} else if ($page->modified()) {
|
||||
$datePublishedRaw = $page->modified();
|
||||
}
|
||||
$dateModifiedRaw = $page->modified() ? $page->modified() : time();
|
||||
$this->webpage->datePublished = date("c", $datePublishedRaw);
|
||||
$this->webpage->dateModified = date("c", $dateModifiedRaw);
|
||||
|
||||
// Webpage Image
|
||||
$filename = false;
|
||||
if ((isset($header->aura['image'])) && ($header->aura['image'] != '')) {
|
||||
$filename = $header->aura['image'];
|
||||
} else if (isset($header->media_order) && ($header->media_order != '')) {
|
||||
$images = explode(',', $header->media_order);
|
||||
if ((is_array($images)) && (!empty($images))) {
|
||||
$filename = $images[0];
|
||||
}
|
||||
}
|
||||
|
||||
if ($filename) {
|
||||
$imagePath = $page->path() . '/' . $filename;
|
||||
if (file_exists($imagePath)) {
|
||||
$size = getimagesize($imagePath);
|
||||
$this->webpage->image = new Image();
|
||||
$this->webpage->image->url = preg_replace('/' . preg_quote($page->urlExtension()) . '$/u', '', $page->url(true)) . '/' . $filename;
|
||||
$this->webpage->image->id = $this->webpage->url . '#primaryimage';
|
||||
$this->webpage->image->width = $size[0];
|
||||
$this->webpage->image->height = $size[1];
|
||||
$this->webpage->image->caption = $this->webpage->title;
|
||||
$this->webpage->image->type = $size['mime'];
|
||||
}
|
||||
}
|
||||
|
||||
if ((isset($header->aura['pagetype'])) && ($header->aura['pagetype'] != '')) {
|
||||
$this->webpage->type = $header->aura['pagetype'];
|
||||
}
|
||||
|
||||
// Author
|
||||
if (($this->grav['config']->get('plugins.aura-authors.enabled')) && isset($page->header()->aura['author'])) {
|
||||
$authors = $this->grav['config']->get('plugins.aura-authors.authors');
|
||||
$key = array_search($page->header()->aura['author'], array_column($authors, 'label'));
|
||||
if ($key !== false) {
|
||||
|
||||
$author = $authors[$key];
|
||||
|
||||
$this->person = new Person();
|
||||
|
||||
$this->person->id = $this->org->url . '#person/' . $author['label'];
|
||||
$this->person->name = $author['name'];
|
||||
$this->person->description = $author['description'];
|
||||
|
||||
// Person SameAs
|
||||
$sameAs = array();
|
||||
foreach ($this->otherPresence as $platform) {
|
||||
$key = 'person-' . $platform;
|
||||
if (isset($author[$key]) && $author[$key] != '') {
|
||||
$sameAs[] = $author[$key];
|
||||
}
|
||||
}
|
||||
$key = 'person-twitter-user';
|
||||
if (isset($author[$key]) && $author[$key] != '') {
|
||||
$this->person->twitterUser = $author[$key];
|
||||
$sameAs[] = 'https://twitter.com/' . $author[$key];
|
||||
}
|
||||
if (!empty($sameAs)) {
|
||||
$this->person->sameAs = $sameAs;
|
||||
}
|
||||
|
||||
// Person Image
|
||||
if ((isset($author['image'])) && (!empty($author['image']))) {
|
||||
$firstImage = reset($author['image']);
|
||||
$imagePath = ROOT_DIR . $firstImage['path'];
|
||||
if (file_exists($imagePath)) {
|
||||
$size = getimagesize($imagePath);
|
||||
$this->person->image = new Image();
|
||||
$this->person->image->url = $this->grav['base_url_absolute'] . '/' . $firstImage['path'];
|
||||
$this->person->image->id = $this->org->url . '#personimage/' . $author['label'];
|
||||
$this->person->image->width = $size[0];
|
||||
$this->person->image->height = $size[1];
|
||||
$this->person->image->caption = $author['name'];
|
||||
$this->person->image->type = $size['mime'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function generateOpenGraphMeta() {
|
||||
$data = array(
|
||||
'og:url' => $this->webpage->url,
|
||||
'og:type' => $this->webpage->type,
|
||||
'og:title' => $this->webpage->title,
|
||||
);
|
||||
if ($this->webpage->description) {
|
||||
$data['og:description'] = $this->webpage->description;
|
||||
}
|
||||
if ($this->webpage->image) {
|
||||
$data['og:image'] = $this->webpage->image->url;
|
||||
$data['og:image:type'] = $this->webpage->image->type;
|
||||
$data['og:image:width'] = $this->webpage->image->width;
|
||||
$data['og:image:height'] = $this->webpage->image->height;
|
||||
}
|
||||
if ($this->grav['config']->get('plugins.aura.org-facebook-appid')) {
|
||||
$data['fb:app_id'] = $this->grav['config']->get('plugins.aura.org-facebook-appid');
|
||||
}
|
||||
if ($this->person) {
|
||||
$data['og:author'] = $this->person->name;
|
||||
} else {
|
||||
$data['og:author'] = $this->org->name;
|
||||
}
|
||||
foreach ($data as $property => $content) {
|
||||
$this->webpage->metadata[$property] = array(
|
||||
'property' => $property,
|
||||
'content' => htmlentities($content),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function generateTwitterMeta() {
|
||||
$data = array(
|
||||
'twitter:card' => 'summary_large_image',
|
||||
'twitter:title' => $this->webpage->title,
|
||||
);
|
||||
if ($this->webpage->description) {
|
||||
$data['twitter:description'] = $this->webpage->description;
|
||||
}
|
||||
if ($this->grav['config']->get('plugins.aura.org-twitter-user')) {
|
||||
$data['twitter:site'] = '@' . $this->grav['config']->get('plugins.aura.org-twitter-user');
|
||||
}
|
||||
if ($this->person && $this->person->twitterUser) {
|
||||
$data['twitter:creator'] = '@' . $this->person->twitterUser;
|
||||
} else {
|
||||
if ($this->grav['config']->get('plugins.aura.org-twitter-user')) {
|
||||
$data['twitter:creator'] = '@' . $this->grav['config']->get('plugins.aura.org-twitter-user');
|
||||
}
|
||||
}
|
||||
if ($this->webpage->image) {
|
||||
$data['twitter:image'] = $this->webpage->image->url;
|
||||
}
|
||||
foreach ($data as $name => $content) {
|
||||
$this->webpage->metadata[$name] = array(
|
||||
'name' => $name,
|
||||
'content' => htmlentities($content),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function generateLinkedInMeta() {
|
||||
$data = array(
|
||||
'article:published_time' => $this->webpage->datePublished,
|
||||
'article:modified_time' => $this->webpage->dateModified,
|
||||
);
|
||||
if ($this->person) {
|
||||
$data['article:author'] = $this->person->name;
|
||||
} else {
|
||||
$data['article:author'] = $this->org->name;
|
||||
}
|
||||
foreach ($data as $property => $content) {
|
||||
$this->webpage->metadata[$property] = array(
|
||||
'property' => $property,
|
||||
'content' => htmlentities($content),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function generateStructuredData() {
|
||||
$organization = array(
|
||||
'@type' => 'Organization',
|
||||
'@id' => $this->org->id,
|
||||
'name' => $this->org->name,
|
||||
'url' => $this->org->url,
|
||||
);
|
||||
|
||||
$website = array(
|
||||
'@type' => 'WebSite',
|
||||
'@id' => $this->website->id,
|
||||
'url' => $this->website->url,
|
||||
'name' => $this->website->name,
|
||||
'publisher' => array(
|
||||
'@id' => $this->org->id,
|
||||
),
|
||||
);
|
||||
|
||||
$webpage = array(
|
||||
'@type' => 'WebPage',
|
||||
'@id' => $this->webpage->id,
|
||||
'url' => $this->webpage->url,
|
||||
'inLanguage' => $this->webpage->language,
|
||||
'name' => $this->webpage->title,
|
||||
'isPartOf' => array(
|
||||
'@id' => $this->website->id,
|
||||
),
|
||||
'datePublished' => $this->webpage->datePublished,
|
||||
'dateModified' => $this->webpage->dateModified,
|
||||
);
|
||||
|
||||
// Add Organization sameAs (if defined)
|
||||
if ($this->org->sameAs) {
|
||||
$organization['sameAs'] = $this->org->sameAs;
|
||||
}
|
||||
|
||||
// Add logo (if defined)
|
||||
if ($this->org->logo) {
|
||||
$organization['logo'] = array(
|
||||
'@type' => 'ImageObject',
|
||||
'@id' => $this->org->logo->id,
|
||||
'url' => $this->org->logo->url,
|
||||
'width' => $this->org->logo->width,
|
||||
'height' => $this->org->logo->height,
|
||||
'caption' => $this->org->logo->caption,
|
||||
);
|
||||
$organization['image'] = array(
|
||||
'@id' => $this->org->logo->id,
|
||||
);
|
||||
}
|
||||
|
||||
// Add page description (if defined)
|
||||
if ($this->webpage->description) {
|
||||
$webpage['description'] = $this->webpage->description;
|
||||
}
|
||||
|
||||
// Add page image (if defined)
|
||||
if ($this->webpage->image) {
|
||||
$webpageImage = array(
|
||||
'@type' => 'ImageObject',
|
||||
'@id' => $this->webpage->image->id,
|
||||
'url' => $this->webpage->image->url,
|
||||
'width' => $this->webpage->image->width,
|
||||
'height' => $this->webpage->image->height,
|
||||
'caption' => $this->webpage->image->caption,
|
||||
);
|
||||
$webpage['primaryImageOfPage'] = array(
|
||||
'@id' => $this->webpage->image->id,
|
||||
);
|
||||
}
|
||||
|
||||
// Additional based on page type i.e. article
|
||||
if ($this->webpage->type == 'article') {
|
||||
$article = array(
|
||||
'@type' => 'Article',
|
||||
'@id' => $this->webpage->url . '#article',
|
||||
'isPartOf' => array(
|
||||
'@id' => $this->webpage->id,
|
||||
),
|
||||
'headline' => $this->webpage->title,
|
||||
'datePublished' => $this->webpage->datePublished,
|
||||
'dateModified' => $this->webpage->dateModified,
|
||||
'mainEntityOfPage' => array(
|
||||
'@id' => $this->webpage->id,
|
||||
),
|
||||
'publisher' => array(
|
||||
'@id' => $this->org->id,
|
||||
),
|
||||
);
|
||||
|
||||
// Add Image
|
||||
if ($this->webpage->image) {
|
||||
$article['image'] = array(
|
||||
'@id' => $this->webpage->image->id,
|
||||
);
|
||||
}
|
||||
|
||||
// Add Author
|
||||
if ($this->person) {
|
||||
// Use Person (if defined)
|
||||
$person = array(
|
||||
'@type' => 'Person',
|
||||
'@id' => $this->person->id,
|
||||
'name' => $this->person->name,
|
||||
);
|
||||
|
||||
// Add Person description (if defined)
|
||||
if ($this->person->description) {
|
||||
$person['description'] = $this->person->description;
|
||||
}
|
||||
|
||||
// Add Person sameAs (if defined)
|
||||
if ($this->person->sameAs) {
|
||||
$person['sameAs'] = $this->person->sameAs;
|
||||
}
|
||||
|
||||
// Add Person image (if defined)
|
||||
if ($this->person->image) {
|
||||
$person['image'] = array(
|
||||
'@type' => 'ImageObject',
|
||||
'@id' => $this->person->image->id,
|
||||
'url' => $this->person->image->url,
|
||||
'width' => $this->person->image->width,
|
||||
'height' => $this->person->image->height,
|
||||
'caption' => $this->person->image->caption,
|
||||
);
|
||||
}
|
||||
$article['author'] = array(
|
||||
'@id' => $this->person->id,
|
||||
);
|
||||
} else {
|
||||
// Use Organization
|
||||
$article['author'] = array(
|
||||
'@id' => $this->org->id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Build the empty structured data block
|
||||
$data = array(
|
||||
'@context' => 'https://schema.org',
|
||||
'@graph' => array(),
|
||||
);
|
||||
|
||||
// Add the elements in order
|
||||
$data['@graph'][] = $organization;
|
||||
$data['@graph'][] = $website;
|
||||
if (isset($webpageImage)) {
|
||||
$data['@graph'][] = $webpageImage;
|
||||
}
|
||||
$data['@graph'][] = $webpage;
|
||||
if (isset($article)) {
|
||||
$data['@graph'][] = $article;
|
||||
}
|
||||
if (isset($person)) {
|
||||
$data['@graph'][] = $person;
|
||||
}
|
||||
|
||||
return json_encode($data, JSON_UNESCAPED_SLASHES);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Grav\Plugin\Aura;
|
||||
|
||||
class Image
|
||||
{
|
||||
public $url;
|
||||
public $id;
|
||||
public $width;
|
||||
public $height;
|
||||
public $caption;
|
||||
public $type;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace Grav\Plugin\Aura;
|
||||
|
||||
class Organization
|
||||
{
|
||||
public $url;
|
||||
public $id;
|
||||
public $name;
|
||||
public $sameAs;
|
||||
public $logo;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Grav\Plugin\Aura;
|
||||
|
||||
class Person
|
||||
{
|
||||
public $id;
|
||||
public $name;
|
||||
public $description;
|
||||
public $sameAs;
|
||||
public $image;
|
||||
public $twitterUser;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Grav\Plugin\Aura;
|
||||
|
||||
class WebPage
|
||||
{
|
||||
public $url;
|
||||
public $id;
|
||||
public $language;
|
||||
public $title;
|
||||
public $description;
|
||||
public $datePublished;
|
||||
public $dateModified;
|
||||
public $image;
|
||||
public $type = 'website';
|
||||
public $metadata;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Grav\Plugin\Aura;
|
||||
|
||||
class WebSite
|
||||
{
|
||||
public $url;
|
||||
public $id;
|
||||
public $name;
|
||||
}
|
||||
Reference in New Issue
Block a user