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