commit
e1be2c6ccb
@ -0,0 +1,59 @@
|
|||||||
|
# v3.0.1
|
||||||
|
## 08/20/2018
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Refactor to remove GravTrait
|
||||||
|
|
||||||
|
# v3.0.0
|
||||||
|
## 08/02/2018
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added shortcode support
|
||||||
|
|
||||||
|
# v2.0.4
|
||||||
|
## 09/28/2017
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Always use HTTPS for YouTube [#21](https://github.com/getgrav/grav-plugin-youtube/pull/21)
|
||||||
|
|
||||||
|
# v2.0.3
|
||||||
|
## 12/23/2016
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed a JavaScript issue [#16](https://github.com/getgrav/grav-plugin-youtube/pull/16)
|
||||||
|
|
||||||
|
# v2.0.2
|
||||||
|
## 05/23/2016
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Supports `youtu.be` based short links
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed for invalid URL with YouTube editor buttons
|
||||||
|
* Fixed editor button to work with Admin v1.1
|
||||||
|
|
||||||
|
# v2.0.1
|
||||||
|
## 11/24/2015
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed issue with case sensitivity when including new `YoutubeTwigExtension`
|
||||||
|
|
||||||
|
# v2.0.0
|
||||||
|
## 11/23/2015
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added player parameters configuration values (@hctom)
|
||||||
|
* Added various YouTube options (@hctom)
|
||||||
|
* Reworked output to use overridable Twig template (@hctom)
|
||||||
|
* Added hebe.json (@hctom)
|
||||||
|
|
||||||
|
# v1.1.0
|
||||||
|
## 10/07/2015
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added admin editor button
|
||||||
|
|
||||||
|
# v1.0.0
|
||||||
|
## 05/09/2015
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* ChangeLog started...
|
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Grav
|
||||||
|
|
||||||
|
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,91 @@
|
|||||||
|
# Grav YouTube Plugin
|
||||||
|
|
||||||
|
`YouTube` is a simple [Grav][grav] Plugin that converts markdown links into responsive embeds.
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
Installing the YouTube plugin can be done in one of two ways. Our GPM (Grav Package Manager) installation method enables you to quickly and easily install the plugin with a simple terminal command, while the manual method enables you to do so via a zip file.
|
||||||
|
|
||||||
|
## GPM Installation (Preferred)
|
||||||
|
|
||||||
|
The simplest way to install this plugin is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm) through your system's Terminal (also called the command line). From the root of your Grav install type:
|
||||||
|
|
||||||
|
bin/gpm install youtube
|
||||||
|
|
||||||
|
This will install the YouTube plugin into your `/user/plugins` directory within Grav. Its files can be found under `/your/site/grav/user/plugins/youtube`.
|
||||||
|
|
||||||
|
## Manual Installation
|
||||||
|
|
||||||
|
To install this plugin, just download the zip version of this repository and unzip it under `/your/site/grav/user/plugins`. Then, rename the folder to `youtube`. You can find these files either on [GitHub](https://github.com/getgrav/grav-plugin-youtube) or via [GetGrav.org](http://getgrav.org/downloads/plugins#extras).
|
||||||
|
|
||||||
|
You should now have all the plugin files under
|
||||||
|
|
||||||
|
/your/site/grav/user/plugins/youtube
|
||||||
|
|
||||||
|
# Config Defaults
|
||||||
|
|
||||||
|
```
|
||||||
|
enabled: true
|
||||||
|
built_in_css: true
|
||||||
|
player_parameters:
|
||||||
|
autoplay: 0
|
||||||
|
cc_load_policy: 0
|
||||||
|
color: red
|
||||||
|
controls: 1
|
||||||
|
disablekb: 0
|
||||||
|
enablejsapi: 0
|
||||||
|
fs: 1
|
||||||
|
hl: ''
|
||||||
|
iv_load_policy: 1
|
||||||
|
loop: 0
|
||||||
|
modestbranding: 0
|
||||||
|
origin: ''
|
||||||
|
playsinline: 0
|
||||||
|
rel: 1
|
||||||
|
showinfo: 1
|
||||||
|
vq: default
|
||||||
|
privacy_enhanced_mode: false
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need to change any value, then the best process is to copy the [youtube.yaml](youtube.yaml) file into your `users/config/plugins/` folder (create it if it doesn't exist), and then modify there. This will override the default settings.
|
||||||
|
|
||||||
|
You can also set any of these settings on a per-page basis by adding them under a `youtube:` setting in your page header. For example:
|
||||||
|
|
||||||
|
---
|
||||||
|
title: YouTube Video
|
||||||
|
youtube:
|
||||||
|
player_parameters:
|
||||||
|
autoplay: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
[plugin:youtube](https://www.youtube.com/watch?v=BK8guP9ov2U)
|
||||||
|
|
||||||
|
This will display a video and auto-play it.
|
||||||
|
|
||||||
|
For more details on the `player_parameters`, please check out the [YouTube official documentation](https://developers.google.com/youtube/player_parameters)
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
To use this plugin you simply need to include a youtube URL in markdown link such as:
|
||||||
|
|
||||||
|
```
|
||||||
|
[plugin:youtube](https://www.youtube.com/watch?v=BK8guP9ov2U)
|
||||||
|
```
|
||||||
|
|
||||||
|
Will be converted into the following embeded HTML:
|
||||||
|
|
||||||
|
```
|
||||||
|
<div class="grav-youtube"><iframe src="https://www.youtube.com/embed/BK8guP9ov2U" frameborder="0" allowfullscreen=""></iframe></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
CSS is also loaded to provide the appropriate responsive layout.
|
||||||
|
|
||||||
|
# Shortcode Syntax
|
||||||
|
|
||||||
|
As of version `3.0` you can now use an alternative _shortcode_ syntax that supports passing in the player parameter values inline
|
||||||
|
|
||||||
|
```
|
||||||
|
[youtube color=white autoplay=1]https://www.youtube.com/watch?v=BK8guP9ov2U[/youtube]
|
||||||
|
```
|
||||||
|
|
||||||
|
[grav]: http://github.com/getgrav/grav
|
@ -0,0 +1,36 @@
|
|||||||
|
(function($){
|
||||||
|
$(function(){
|
||||||
|
$('body').on('grav-editor-ready', function() {
|
||||||
|
var Instance = Grav.default.Forms.Fields.EditorField.Instance;
|
||||||
|
Instance.addButton({
|
||||||
|
yt: {
|
||||||
|
identifier: 'yt-video',
|
||||||
|
title: 'YouTube Video',
|
||||||
|
label: '<i class="fa fa-fw fa-youtube"></i>',
|
||||||
|
modes: ['gfm', 'markdown'],
|
||||||
|
action: function(_ref) {
|
||||||
|
var codemirror = _ref.codemirror, button = _ref.button, textarea = _ref.textarea;
|
||||||
|
button.on('click.editor.yt',function() {
|
||||||
|
var videoURL = prompt("Enter the YouTube Video URL. E.g. https://www.youtube.com/watch?v=vQ4qK36UenI");
|
||||||
|
|
||||||
|
if (videoURL) {
|
||||||
|
var text = '[plugin:yt](' + videoURL + ')';
|
||||||
|
|
||||||
|
//Add text to the editor
|
||||||
|
var pos = codemirror.getDoc().getCursor(true);
|
||||||
|
var posend = codemirror.getDoc().getCursor(false);
|
||||||
|
|
||||||
|
for (var i=pos.line; i<(posend.line+1);i++) {
|
||||||
|
codemirror.replaceRange(text+codemirror.getLine(i), { line: i, ch: 0 }, { line: i, ch: codemirror.getLine(i).length });
|
||||||
|
}
|
||||||
|
|
||||||
|
codemirror.setCursor({ line: posend.line, ch: codemirror.getLine(posend.line).length });
|
||||||
|
codemirror.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(jQuery);
|
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grav\Plugin\YT\Twig;
|
||||||
|
|
||||||
|
|
||||||
|
use Grav\Common\Grav;
|
||||||
|
|
||||||
|
class YTTwigExtension extends \Twig_Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns extension name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'YTTwigExtension';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new \Twig_SimpleFunction('yt_embed_url', [$this, 'embedUrl']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds YouTube video embed URL.
|
||||||
|
*
|
||||||
|
* @param string $video_id
|
||||||
|
* @param array $player_parameters
|
||||||
|
* @param bool $privacy_enhanced_mode
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function embedUrl($video_id, array $player_parameters = array(), $privacy_enhanced_mode = FALSE)
|
||||||
|
{
|
||||||
|
$grav = Grav::instance();
|
||||||
|
|
||||||
|
// build base video embed URL (while respecting privacy enhanced mode setting)
|
||||||
|
$url = 'https://www.youtube' . ($privacy_enhanced_mode ? '-nocookie' : '') . '.com/embed/' . $video_id;
|
||||||
|
|
||||||
|
// filter player parameters to only those not matching YouTube defaults
|
||||||
|
$filtered_player_parameters = array();
|
||||||
|
foreach ($player_parameters as $key => $value) {
|
||||||
|
$parameter_blueprint = $grav['config']->blueprints()->get('plugins.yt.player_parameters.' . $key);
|
||||||
|
|
||||||
|
// configured value matches YouTube default -> skip parameter
|
||||||
|
if (isset($parameter_blueprint['default']) && $parameter_blueprint['default'] == $value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filtered_player_parameters[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// append query string (if any)
|
||||||
|
if (!empty($filtered_player_parameters) && ($query_string = http_build_query($filtered_player_parameters))) {
|
||||||
|
$url .= '?' . $query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
.grav-yt {
|
||||||
|
display: inline;
|
||||||
|
width: 280px;
|
||||||
|
height: 135px;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"project":"grav-plugin-yt",
|
||||||
|
"platforms":{
|
||||||
|
"grav":{
|
||||||
|
"nodes":{
|
||||||
|
"theme":[
|
||||||
|
{
|
||||||
|
"source":"/",
|
||||||
|
"destination":"/user/plugins/yt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
namespace Grav\Plugin\Shortcodes;
|
||||||
|
|
||||||
|
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
|
||||||
|
|
||||||
|
class YTShortcode extends Shortcode
|
||||||
|
{
|
||||||
|
const YOUTUBE_REGEX = '/(?:https?:\/{2}(?:(?:www.youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=))|(?:youtu\.be\/)))((?:videoseries\?list=[a-zA-Z0-9_-]{34})|[a-zA-Z0-9_-]{11})/';
|
||||||
|
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->shortcode->getHandlers()->add('yt', function(ShortcodeInterface $sc) {
|
||||||
|
|
||||||
|
// Get shortcode content and parameters
|
||||||
|
$url = $sc->getContent();
|
||||||
|
$params = $sc->getParameters();
|
||||||
|
$privacy_mode = $sc->getParameter('privacy_enhanced_mode');
|
||||||
|
|
||||||
|
if ($url) {
|
||||||
|
preg_match($this::YOUTUBE_REGEX, $url, $matches);
|
||||||
|
$search = $matches[0];
|
||||||
|
|
||||||
|
// double check to make sure we found a valid YouTube video ID
|
||||||
|
if (!isset($matches[1])) {
|
||||||
|
return $search;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Twig $twig */
|
||||||
|
$twig = $this->grav['twig'];
|
||||||
|
|
||||||
|
// build the replacement embed HTML string
|
||||||
|
$replace = $twig->processTemplate('partials/yt.html.twig', array(
|
||||||
|
'player_parameters' => $params,
|
||||||
|
'privacy_enhanced_mode' => $privacy_mode,
|
||||||
|
'video_id' => $matches[1],
|
||||||
|
));
|
||||||
|
|
||||||
|
// do the replacement
|
||||||
|
return str_replace($search, $replace, $search);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
<div class="grav-yt">
|
||||||
|
<iframe src="{{- yt_embed_url(video_id, player_parameters, privacy_enhanced_mode) -}}" frameborder="0" allowfullscreen></iframe>
|
||||||
|
</div>
|
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* YT
|
||||||
|
*
|
||||||
|
* This plugin embeds YouTube video from markdown URLs
|
||||||
|
*
|
||||||
|
* Licensed under MIT, see LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Grav\Plugin;
|
||||||
|
|
||||||
|
use Grav\Common\Data\Data;
|
||||||
|
use Grav\Common\Plugin;
|
||||||
|
use Grav\Common\Page\Page;
|
||||||
|
use Grav\Common\Twig\Twig;
|
||||||
|
use Grav\Plugin\YT\Twig\YTTwigExtension;
|
||||||
|
use RocketTheme\Toolbox\Event\Event;
|
||||||
|
|
||||||
|
class YTPlugin extends Plugin
|
||||||
|
{
|
||||||
|
const YOUTUBE_REGEX = '(?:https?:\/{2}(?:(?:www.youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=))|(?:youtu\.be\/)))((?:videoseries\?list=[a-zA-Z0-9_-]{34})|[a-zA-Z0-9_-]{11})';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of subscribed events.
|
||||||
|
*
|
||||||
|
* @return array The list of events of the plugin of the form
|
||||||
|
* 'name' => ['method_name', priority].
|
||||||
|
*/
|
||||||
|
public static function getSubscribedEvents()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'onPluginsInitialized' => ['onPluginsInitialized', 0],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize configuration.
|
||||||
|
*/
|
||||||
|
public function onPluginsInitialized()
|
||||||
|
{
|
||||||
|
if ($this->isAdmin()) {
|
||||||
|
$this->enable([
|
||||||
|
'onTwigSiteVariables' => ['onTwigSiteVariables', 0],
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->enable([
|
||||||
|
'onPageContentRaw' => ['onPageContentRaw', 0],
|
||||||
|
'onTwigExtensions' => ['onTwigExtensions', 0],
|
||||||
|
'onTwigSiteVariables' => ['onTwigSiteVariables', 0],
|
||||||
|
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
|
||||||
|
'onShortcodeHandlers' => ['onShortcodeHandlers', 0],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add content after page content was read into the system.
|
||||||
|
*
|
||||||
|
* @param Event $event An event object, when `onPageContentRaw` is fired.
|
||||||
|
*/
|
||||||
|
public function onPageContentRaw(Event $event)
|
||||||
|
{
|
||||||
|
/** @var Page $page */
|
||||||
|
$page = $event['page'];
|
||||||
|
/** @var Twig $twig */
|
||||||
|
$twig = $this->grav['twig'];
|
||||||
|
/** @var Data $config */
|
||||||
|
$config = $this->mergeConfig($page, TRUE);
|
||||||
|
|
||||||
|
if ($config->get('enabled')) {
|
||||||
|
// Get raw content and substitute all formulas by a unique token
|
||||||
|
$raw = $page->getRawContent();
|
||||||
|
|
||||||
|
// build an anonymous function to pass to `parseLinks()`
|
||||||
|
$function = function ($matches) use ($twig, $config) {
|
||||||
|
$search = $matches[0];
|
||||||
|
|
||||||
|
// double check to make sure we found a valid YouTube video ID
|
||||||
|
if (!isset($matches[1])) {
|
||||||
|
return $search;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the replacement embed HTML string
|
||||||
|
$replace = $twig->processTemplate('partials/yt.html.twig', array(
|
||||||
|
'player_parameters' => $config->get('player_parameters'),
|
||||||
|
'privacy_enhanced_mode' => $config->get('privacy_enhanced_mode'),
|
||||||
|
'video_id' => $matches[1],
|
||||||
|
));
|
||||||
|
|
||||||
|
// do the replacement
|
||||||
|
return str_replace($search, $replace, $search);
|
||||||
|
};
|
||||||
|
|
||||||
|
// set the parsed content back into as raw content
|
||||||
|
//$page->setRawContent($this->parseLinks($raw, $function, $this::YOUTUBE_REGEX));
|
||||||
|
$page->setRawContent($this->parseLinks($raw, $function));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Twig Extensions.
|
||||||
|
*/
|
||||||
|
public function onTwigExtensions()
|
||||||
|
{
|
||||||
|
require_once __DIR__ . '/classes/Twig/YTTwigExtension.php';
|
||||||
|
$this->grav['twig']->twig->addExtension(new YTTwigExtension());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set needed variables to display breadcrumbs.
|
||||||
|
*/
|
||||||
|
public function onTwigSiteVariables()
|
||||||
|
{
|
||||||
|
if (!$this->isAdmin() && $this->config->get('plugins.yt.built_in_css')) {
|
||||||
|
$this->grav['assets']->add('plugin://yt/css/yt.css');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isAdmin() && $this->config->get('plugins.yt.add_editor_button')) {
|
||||||
|
$this->grav['assets']->add('plugin://yt/admin/editor-button/js/button.js');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add current directory to twig lookup paths.
|
||||||
|
*/
|
||||||
|
public function onTwigTemplatePaths()
|
||||||
|
{
|
||||||
|
$this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize shortcodes
|
||||||
|
*/
|
||||||
|
public function onShortcodeHandlers()
|
||||||
|
{
|
||||||
|
$this->grav['shortcode']->registerAllShortcodes(__DIR__.'/shortcodes');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
enabled: true
|
||||||
|
built_in_css: true
|
||||||
|
add_editor_button: true
|
||||||
|
player_parameters:
|
||||||
|
autoplay: 0
|
||||||
|
cc_load_policy: 0
|
||||||
|
color: red
|
||||||
|
controls: 1
|
||||||
|
disablekb: 0
|
||||||
|
enablejsapi: 0
|
||||||
|
fs: 1
|
||||||
|
hl: ''
|
||||||
|
iv_load_policy: 1
|
||||||
|
loop: 0
|
||||||
|
modestbranding: 0
|
||||||
|
origin: ''
|
||||||
|
playsinline: 0
|
||||||
|
rel: 1
|
||||||
|
showinfo: 1
|
||||||
|
vq: default
|
||||||
|
privacy_enhanced_mode: false
|
Loading…
Reference in new issue