sgalinski / sg-youtube
A solution for embedding YouTube videos, playlists, or channels easily into TYPO3 pages.
Requires
- typo3/cms-core: ^12.4.0
Replaces
- sgalinski/sg_youtube: 8.0.0
- dev-master
- 8.0.0
- 7.2.0
- 7.1.11
- 7.1.10
- 7.1.9
- 7.1.8
- 7.1.7
- 7.1.6
- 7.1.5
- 7.1.4
- 7.1.3
- 7.1.2
- 7.1.1
- 7.1.0
- 7.0.0
- v6.x-dev
- 6.0.7
- 6.0.6
- 6.0.5
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0.0
- 5.3.0
- 5.2.4
- 5.2.3
- 5.2.2
- 5.2.1
- 5.2.0
- 5.1.5
- 5.1.4
- 5.1.3
- 5.1.2
- 5.1.1
- 5.1.0
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.8.2
- 4.8.1
- 4.8.0
- 4.7.0
- 4.6.3
- 4.6.2
- 4.6.1
- 4.6.0
- 4.5.0
- 4.4.1
- 4.4.0
- 4.3.1
- 4.3.0
- 4.2.8
- 4.2.7
- 4.2.6
- 4.2.5
- 4.2.4
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.1
- 4.1.0
- 4.0.0
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.0
- 3.0.0
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.1
- 2.0.0
- 1.1.2
- 1.1.1
- 1.1.0
This package is not auto-updated.
Last update: 2024-11-01 21:20:54 UTC
README
License: GNU GPL, Version 2
Repository: https://gitlab.sgalinski.de/typo3/sg_youtube
Please report bugs here: https://gitlab.sgalinski.de/typo3/sg_youtube
Installation / Integration
First install the extension and activate it in the Extension Manager.
TypoScript integration
- Include the TypoScript in Configuration/TypoScript/setup.typoscript and constants.typoscript in your theme.
- Add your YouTube API key:
plugin.tx_sgyoutube {
settings {
# cat=plugin.tx_sgyoutube/file; type=string; label=YouTube API Key
apiKey = <your-api-key>
}
}
Registration for more than the free 10.000 quotas per day
It's not 1 quota per 1 API call. Each API has its own costs, which can be seen in the link below.
Currently, at the version 3.2.1 we are using the following APIs:
- "search/list" for channel videos
- "playlistItems/list" for videos from a specific playlist
- "videos/list" for getting the details for each video and the localizations, if needed.
The maximum quota costs would be "102" at the moment for rendering the latest videos from a channel with the video details and translations.
YouTube API Services - Audit and Quota Extension Form
Caching behaviour
Because of the quota costs we implemented a caching for the calls for each day. The response from the APIs will be saved and used for 24 hours. Normally the site cache would do it, but it could be, that the cache will be cleared multiple times in a row, or that the plugin is on an uncached page. The TYPO3 registry is used as a cache. The cleanup is handled on the fly.
If the ?disableYoutubeCache=1
parameter is added to the URL, this cache will be ignored as well.
Possible way to solve the quota limit, if it's still reached
You can use a different API key for specific sites. You can implement a TypoScript page uid check and just change the key from the "TypoScript integration" topic.
Making changes in JavaScript/CSS
We are shipping the extension with source files and already minified assets. By default, the minified assets are loaded in the Layout, so that the extension works out of the box just with plug and play. Should you want to change this behavior, you can do the following:
- Override the layout path in TypoScript local/project_theme/Configuration/TypoScript/Extensions/SgYouTube/Constants.typoscript
plugin.tx_sgyoutube {
settings {
apiKey = MY_KEY
}
view {
layoutRootPath = EXT:project_theme/Resources/Private/Layouts/SgYouTube/
}
}
- Create a new layout file omitting the assets that you would like to change (for example, loading without CSS)
<div class="tx-sg-youtube">
<f:asset.script identifier="sgVideoJs" src="EXT:sg_youtube/Resources/Public/JavaScript/Dist/main.bundled.min.js" />
<f:render section="main"/>
</div>
- Import the CSS or JavaScript source files in your respective asset pipeline and add them externally.
Compiling CSS/JS assets with SGC
- Install the sgalinski/sgc-core library via composer
- Add the sg-youtube extension paths in the .sgc-config.json
- Remove the loading of the compiled CSS/JS assets from Resources/Private/Templates/Youtube/Index.html
- Add import the scss and js module file in the corresponding main.scss and main.js
- Initialize the javascript modules in your main.js:
new SgVideoLightbox(); SgVideo.initDefault();
- If you want to recompile the JS with SGC, you must add
excludeFromQa: ['!**/Backend/**/*']
to your .sgc-config.js and also set your main extension in extensions to sg-youtubeextensions: ['sg-youtube']
Compiling SASS only without SGC
Example:
npm install -g sass
npx sass ./Resources/Public/Sass/Bootstrap5/main.scss ./Resources/Public/StyleSheets/Bootstrap5/main.min.css --style compressed --no-source-map
Using the Bootstrap 5 templates
If you want to use the Bootstrap 5 templates, you have to first install Bootstrap 5 in your theme to use its styles and JavaScript.
Afterwards simply set the plugin.tx_project_theme.config.bootstrapVersion
TypoScript setup variable to 5.
Using Events to Customize YouTube API Results in TYPO3
This documentation explains how to leverage custom events in your TYPO3 extension to manipulate the results of YouTube API calls. By using these events, you can modify the API parameters, filter results, and further customize the JSON data returned from YouTube.
Available Events
The following events are dispatched in the YouTube video rendering process:
BeforeYoutubeCallEvent
AfterYoutubeCallEvent
AfterFilterVideosEvent
AfterMapCustomThumbnailsEvent
Event Listeners
1. BeforeYoutubeCallEvent
Description: This event is triggered before making the YouTube API call, allowing you to modify the API parameters.
Example Use Case: Change API Key or manipulate other paramters
<?php
namespace Vendor\Extension\EventListener;
use SGalinski\SgYoutube\Event\BeforeVimeoCallEvent;
class BeforeYoutubeCallEventListener
{
public function __invoke(BeforeVimeoCallEvent $event): void
{
// Change the API key
$event->setApiKey('your-new-api-key');
// Extend the max results limit by 10 videos
$event->setMaxResultsWithFilters($event->getMaxResultsWithFilters() + 10);
}
}
2. AfterYoutubeCallEvent
Description: Add Custom Data to JSON Array
Example Use Case: Change API Key or manipulate other paramters
<?php
namespace SGalinski\SgYoutube\EventListeners;
use SGalinski\SgYoutube\Event\AfterVimeoCallEvent;
class AfterYoutubeCallEventListener
{
public function __invoke(AfterVimeoCallEvent $event): void
{
$jsonArray = $event->getJsonArray();
// Add custom data
$jsonArray['customData'] = 'This is some custom data';
$event->setJsonArray($jsonArray);
}
}
3. AfterFilterVideosEvent
Description: This event is triggered after the videos have been filtered, allowing you to further manipulate the filtered results.
Example Use Case: Remove the 10 videos that we added initially with the first event
<?php
namespace SGalinski\SgYoutube\EventListeners;
use SGalinski\SgYoutube\Event\AfterFilterVideosEvent;
class AfterFilterVideosEventListener
{
public function __invoke(AfterFilterVideosEvent $event): void
{
// Modify the jsonArray if needed
$jsonArray = $event->getJsonArray();
// Add some custom processing here
// For example let's remove the extra 10 videos that we added in the other event
if (count($jsonArray['items']) > 10) {
array_splice($jsonArray['items'], 0, 10);
}
$event->setJsonArray($jsonArray);
}
}
4. AfterMapCustomThumbnailsEvent
Description: This event is triggered after custom thumbnails have been mapped, allowing you to modify the JSON array one last time before rendering.
Example Use Case: Use a custom thumbnail for all videos in the list
<?php
namespace SGalinski\SgYoutube\EventListeners;
use SGalinski\SgYoutube\Event\AfterMapCustomThumbnailsEvent;
class AfterMapCustomThumbnailsEventListener
{
public function __invoke(AfterMapCustomThumbnailsEvent $event): void
{
$jsonArray = $event->getJsonArray();
// Add a custom thumbnail URL
foreach ($jsonArray['items'] as &$item) {
$item['customThumbnail'] = 'https://example.com/custom-thumbnail.jpg';
}
$event->setJsonArray($jsonArray);
}
}
To enable the events just register them in your Services.php as follows (you can use yaml instead if you prefer):
$services->set(BeforeYoutubeCallEventListener::class)
->tag('event.listener', ['event' => BeforeYoutubeCallEvent::class]);
$services->set(AfterYoutubeCallEventListener::class)
->tag('event.listener', ['event' => AfterYoutubeCallEvent::class]);
$services->set(AfterFilterVideosEventListener::class)
->tag('event.listener', ['event' => AfterFilterVideosEvent::class]);
$services->set(AfterMapCustomThumbnailsEventListener::class)
->tag('event.listener', ['event' => AfterMapCustomThumbnailsEvent::class]);
Setting Up the Frontend Filers
Step 1: Adding the Plugin to a Page
- In the TYPO3 backend, create or edit the page where you want to display YouTube videos.
- Add a new content element and select the YouTube plugin from the list.
- Provide the necessary YouTube details in the plugin settings (like YouTube API key, video/channel/playlist ID, max results, etc.).
Step 2: Disable caching for the extension and Cache validation for your web page
- In the TYPO3 backend, go to Settings -> Extensions and open the sg_youtube settings. Tick the box that says 'uncached' and save.
- This way the the extension will not cache the results and the the data will be loaded dynamically based on the filter settings.
- Set
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['enforceValidation'] = false
in your TYPO3 configuration, otherwise using the frontend filters may result in a 404 page in some instances.
Step 3: Configuring Filters via FlexForm
- In the plugin's FlexForm settings, you will see a section for "Filters."
- Depending on your site configuration, filters will be available in a select field. You can select the filters you want to display (like search term, video duration, etc.).
- Save your settings and publish the page.
3. Using Filters in the Frontend
Once filters are enabled, they will appear on the frontend in a form, allowing users to interact with the displayed videos dynamically. For example:
- Search Term: Allows users to input a search term to filter videos based on keywords.
- Duration Filter: Provides a dropdown to filter videos by length (short, medium, long, etc.).
The filter values are sent to the YouTube API, and the video list updates based on the selected criteria.
4. TypoScript Configuration for Filters
To define custom filters, the plugin uses TypoScript. Below is an example configuration and an explanation of each section:
Example TypoScript Configuration
filters {
searchTerm {
label = LLL:EXT:sg_youtube/Resources/Private/Language/locallang.xlf:filter.searchTerm
partial = Filters/TextField
filterClass = SGalinski\SgYoutube\Filter\QueryStringFilter
defaultValues {
# search = test
}
position = top
}
duration {
label = LLL:EXT:sg_youtube/Resources/Private/Language/locallang.xlf:filter.duration
partial = Filters/Dropdown
filterClass = SGalinski\SgYoutube\Filter\DurationFilter
position = top
options {
0 {
label = LLL:EXT:sg_youtube/Resources/Private/Language/locallang.xlf:filter.duration.0
value = 1
}
1 {
label = LLL:EXT:sg_youtube/Resources/Private/Language/locallang.xlf:filter.duration.1
value = 2
}
}
}
}
submitButton {
position = top
cssClass = btn btn-default
label = LLL:EXT:sg_youtube/Resources/Private/Language/locallang.xlf:filter.submitButton
}
Explanation of the Configuration
filters
This TypoScript object defines all the available filters for the YouTube plugin. Each filter is a separate sub-object, like searchTerm
and duration
in the example.
Filter Fields
searchTerm
(Text Field)- label: The label for the filter form field. This can be translated using the TYPO3 language file (
locallang.xlf
). - partial: Specifies which partial file to use for rendering the filter. In this case, it points to a text field (
Filters/TextField
). - filterClass: This is the PHP class responsible for processing the filter and applying it to the YouTube API request. For the
searchTerm
, it's aQueryStringFilter
. - defaultValues: You can specify default values for the filter (commented out in the example).
- position: Defines where the filter should be displayed on the page. It can be
top
(above the video list) orbottom
(below the video list).
- label: The label for the filter form field. This can be translated using the TYPO3 language file (
duration
(Dropdown)- label: The label for the filter form field.
- partial: Points to a dropdown partial (
Filters/Dropdown
). - filterClass: This is the PHP class responsible for processing the filter. For
duration
, it'sDurationFilter
. - options: This section defines the options for the dropdown, each with a
label
(for the user to see) and avalue
(sent to the API). - position: Indicates where the filter should be displayed on the page.
submitButton
- Defines the configuration for the submit button:
- position: Determines where the submit button is placed in the form (
top
in this case). It acceptstop
,bottom
orboth
- cssClass: Adds CSS classes for styling the button.
- label: Provides the text for the submit button (translatable using
locallang.xlf
).
- position: Determines where the submit button is placed in the form (
5. Adding Custom Filters
You can easily extend the plugin by defining your own filters in TypoScript:
Create a New Filter Add a new filter object under
filters
in your TypoScript setup. For example, if you want to filter by video quality, your configuration might look like this:filters { quality { label = LLL:EXT:sg_youtube/Resources/Private/Language/locallang.xlf:filter.quality partial = Filters/Dropdown filterClass = SGalinski\SgYoutube\Filter\QualityFilter position = top options { 0 { label = HD value = hd } 1 { label = SD value = sd } } } }
Implement the Filter Logic You will need to define the corresponding PHP
filterClass
that handles the logic for applying the filter to the YouTube API request. For example, theQualityFilter
class would process the selected video quality and add the appropriate parameters to the API request. It must implement the FilterInterface interface. The modifyRequest method is called before sending the reuqest, while the modifyResponse method is called after receiving the response.
6. Working with Filter Positions
You can choose where filters are displayed (above or below the video list) by setting the position
attribute in the TypoScript configuration. This allows you to create a flexible layout for filters:
- Filters with
position = top
will be displayed before the video list. - Filters with
position = bottom
will be displayed after the video list.
For example:
filters {
searchTerm {
position = top
}
duration {
position = bottom
}
}
7. Debugging and Error Handling
If something goes wrong (e.g., videos aren't displayed, or the API request fails), here are a few things to check:
- Make sure the YouTube API key is correctly configured.
- Check the TypoScript configuration for errors (e.g., missing or incorrect filter definitions).
- Look for error messages in the TYPO3 backend log for issues related to the plugin.
8. Conclusion
With this flexible filter system, you can easily customize the YouTube video list based on user input. By defining filters in TypoScript and adding them to the plugin's FlexForm, you provide an interactive and tailored experience for your site's visitors.
If you need to add more filters, just extend the TypoScript configuration, create the necessary filter classes, and you're ready to go!