Output content from wordpress plugin and rewrite rules - php

I have created a wordpress plugin that has a filter on the_content, looking for a specific tag then outputting the plugin content in place of that tag.
I would now like to use rewrite rules to call the plugin and output the data within the template, but I'm not finding much help.
Can someone provide an example, or some guidance on how to add a rewrite rule using the built in wp methods and calling my methods in the plugin which outputs some content.
Ideally, I would like shop/ to be matched and then pass everything after shop to my dispatch method on my plugin so that I can have shop/category/shirts or shop/product/the-cool-shirt. My dispatch method would handle breaking apart the rest of the url and calling methods accordingly.

This can get rather interesting. I had to do this for a plugin at one point, I don't have it in front of me, so this it out of memory, but the general idea should be correct.
<?php
add_action('init', 'rewrite_rules');
function rewrite_rules() {
global $wp, $wp_rewrite;
$wp_rewrite->add_rule('(widget1|widget2|widget3)/([a-zA-Z0-9_-]{3,50})$', 'index.php?pagename=listing&category=$matches[1]&subcategory=$matches[2]', 'top' );
$wp->add_query_var( 'category' );
$wp->add_query_var( 'subcategory' );
$wp_rewrite->flush_rules();
}
?>
Using regular expressions is a monumental task in itself, I believe I used this site: http://tools.netshiftmedia.com/regexlibrary/ for help.
I also used FakePage plugin to actually display my custom "dynamic" pages, as I called them, but I suppose everything in WP is technically dynamic.
http://scott.sherrillmix.com/blog/blogger/creating-a-better-fake-post-with-a-wordpress-plugin/
Let me know if you need more help.

I did something very similar not long ago, and I did it by cheating.
If you find the built in rewrite rules too complicated or unable to do the job, you may find it easier to catch the request and filter the results. A simplified version:
add_action('parse_request', 'my_parse_request');
function my_parse_request (&$wp) {
$path = $wp->request;
$groups = array();
if (preg_match("%shop/product/([a-zA-Z0-9-]+)%", $path, $groups)) {
$code = $groups[1];
$product = get_product($code); // your own code here
if (isset($product)) {
add_filter('the_posts', 'my_product_filter_posts');
}
}
}
function my_product_filter_posts ($posts) {
ob_start();
echo "stuff goes here"; // your body here
$content = ob_get_contents();
ob_end_clean();
return array(new DummyResult(0, "Product name", $content));
}
To explain:
The action on parse_request is called before the database lookup. Based on the URL, it installs the other actions and filters.
The filter on posts replaces the results of the database lookup with fake results.
DummyResult is a simple class that has the same fields as a post, or just enough of them to get away with it:
class DummyResult {
public $ID;
public $post_title;
public $post_content;
public $post_author;
public $comment_status = "closed";
public $post_status = "publish";
public $ping_status = "closed";
public $post_type = "page";
public $post_date = "";
function __construct ($ID, $title, $content) {
$this->ID = $ID;
$this->post_title = $title;
$this->post_content = $content;
$this->post_author = get_default_author(); // implement this function
}
}
There's a lot of homework left for the reader in the above, but it's an ugly, working approach. You'll probably want to add a filter for template_redirect, to replace the normal page template with a product-specific one. And you may need to adjust the URL regex if you want pretty permalinks.

Related

Is it possible to link to other static pages in a Timber template?

Currently, to link to a "FAQ" page, I have the following:
Check out our FAQ page.
However, I'd like to be able to link to other internal pages in my WordPress theme without manually writing in the URL parameters after it. Something like:
Check out our FAQ page.
Is this not possible in Timber? I've checked through the docs but don't see any references to it, but I feel like I must be missing something.
Wordpress has two functions to resolve it: get_page_by_path() and get_permalink()
get_page_by_path('page-slug');
get_permalink(page_id);
Using Timber you could write something like this calling a Timber function:
{{ function('get_permalink', function('get_page_by_path', 'page-slug')) }}
But sure, you should define a wp function to not be insane. You can add functions to WordPress using the functions.php file, even you should have defined a class to extends Timber (if not, copy and paste it)
class StarterSite extends Timber\Site {
public function __construct() {
add_filter( 'timber/twig', array( $this, 'add_to_twig' ) );
add_filter( 'timber/context', array( $this, 'add_to_context' ) );
$this->add_routes();
parent::__construct();
}
public function add_to_context( $context ) {
$context['menu'] = new Timber\Menu();
$context['site'] = $this;
return $context;
}
public function add_to_twig( $twig ) {
$twig->addFunction( new Timber\Twig_Function( 'get_permalink_by_slug', function($slug) {
return get_permalink( get_page_by_path($slug) );
} ) );
return $twig;
}
}
new StarterSite();
As you can see I defined a Twig function named get_page_by_slug that receives a string with the page slug. Now, you can write it on your templates:
{{ get_permalink_by_slug('page-slug') }}
Enjoy :)
You can add the pages into your context using the filter timber_context
add_filter('timber_context', 'add_to_context');
function add_to_context($context){
/* this is where you can add your own data to Timber's context object */
$extraLinks = [];
$extraLinks['faq'] = get_permalink($faq_ID);
$context['site']['extraLinks'] = $extraLinks;
return $context;
}
So you can call in your twig file
Check out our FAQ page.
source

Pass variable to _preprocess_node function for use in node template

I've been racking my brains over this one but I'll do my best to describe the problem as best as possible. I have a custom function written within template.php, with a bunch of conditionals. When a condition is true, I would like to assign a value to a variable, and then pass that variable intro a node preprocess function that allows that variables to be rendered on a node template.
The function containing the condition:
function _mytheme_date_repeat_string($vars) {
$exdate_pos = strpos($rrule['WKST'], 'EXDATE:');
if($exdate_pos > 0) {
$vars['testvar'] = 'abc123';
}
}
The preprocess function that I would like to render the variable in for node template use:
function mytheme_preprocess_node(&$vars, $hook) {
$vars['new_variable'] = $testvar;
}
Intended usage in node.tpl.php:
<?php print $new_variable; ?>
I'm not great with PHP, but I know enough about programming to know that variable scope might be an issue here. What would be the best way to implement this? Any guidance is greatly appreciated.
Thanks,
Mark.
If it is not called, your _mytheme_date_repeat_string() function will never be executed. Preprocess functions (ie. any function starting mytheme_preprocess_, are called automatically by Drupal's theme system.
What you need is either move the code of _mytheme_date_repeat_string() in mytheme_preprocess_node() or refactor it and call it.
function _mytheme_date_repeat_string($rrule) {
$exdate_pos = strpos($rrule['WKST'], 'EXDATE:');
if($exdate_pos > 0) {
return 'abc123';
}
else {
return NULL;
}
}
/**
* Prepares variables for node templates.
*/
function mytheme_preprocess_node(&$variables, $hook) {
// Get $rrule from somewhere
$rrule = ... ;
$testvar = _mytheme_date_repeat_string($rrule);
if ($testvar) {
$variables['new_variable'] = $testvar;
}
}
You code does not show where the $rrule calue comes from. I assume you would get it for $variables['node'].

Wordpress add_rewrite_tag(), add_rewrite_rule(), and post_link()

I am trying to do the following:
Rewrite the URL structure of my WordPress installation so that a language field is in there. E.g. http://www.mydomain.com/lang/
I want to then take the input from /lang/ and use it to display the appropriate content. E.g. if lang is 'en' I will take custom fields in English and display the theme in English.
Here is what I have so far:
<?php
function add_directory_rewrite() {
global $wp_rewrite;
add_rewrite_tag('%lang%', '(.+)');
add_rewrite_rule('^/(.+)/', 'index.php?p=$matches[1]&lang=$matches[2]', 'top');
add_permastruct('lang', '%lang%');
}
add_action( 'init', 'add_directory_rewrite' );
?>
This works as far as getting the language but the problem I am facing is now the_permalink() has "/%lang%/" where /en/ is supposed to be or /fr/ or /de/ or whatever language. To add more detail my permalink structure is /%lang%/%category%/%postname%/ and lets say I have a category called food and a post with the title chicken, the_permalink will generate http://www.mydomain.com/%lang%/food/chicken/
Any idea what I'm doing wrong? Cheers.
You additionally need to add a function that will take the permalink that contains the erroneous '/%lang%/' segment, and replace it with the appropriate default language for the post. Typically you can do this either by the 'pre_post_link' filter, or the 'post_link' filter. If you use the former, you will be creating the permalink from scratch (totally custom urls that use nothing that core WP has to offer). If the latter is use, then you can filter the permalink after WP has done it's magic, but before it is used on the site. Here is an example:
function lou_rewrite_lang_in_permalink($permalink, $post, $leavename) {
// find the default post language via a function you have created to
// determine the default language url. this could be based on the current
// language the user has selected on the frontend, or based on the current
// url, or based on the post itself. it is up to you
$default_post_language = get_default_post_lang($post);
// once you have the default language, it is a simple search and replace
return str_replace('%lang%', $lang, $permalink);
}
add_filter('post_link', 'lou_rewrite_lang_in_permalink', 11, 3);
You don't mention it so I will. With your original solo function, you are gunna have a hard time if it is stand alone. The reason is because, though you have told the rewriter that a new url segment exists, you didn't tell WordPress to expect it as a url param. Thus, even though you have some fancy code to rewrite the url and tell WordPress the fancy lang param, WordPress does not know that it should be looking for it, and thus ignores it. You need to add something like this to rectify that:
function lou_add_lang_query_var($vars) {
// tell WP to expect the lang query_var, which you can then later use
$vars[] = 'lang';
// return the new list of query vars, which includes our lang param
return array_unique($vars);
}
add_filter('query_vars', 'lou_add_lang_query_var', 10, 1);
This will tell the WP() class that it needs to accept the 'lang' instead of just skipping over it. Then later you can do something like this to figure out that the current page sent as it's language:
function lou_somefunction() {
// do stuff
...
// access the $wp object
global $wp;
// determine the language from the query_vars of the current page
$lang = $wp->query_var['lang'];
// do other stuff with $lang
...
}
Hope this helps.
EDIT
First I want to say, this is an absolute travesty that language urls are not natively supported by WordPress. I have honestly never needed to do this, but most of my clients are not international companies, with international needs. I will be submitting something to WordPress in code form to solve this in a later version, but as of now, you will need a plugin like the one I have created below.
So I did a lot of investigation to make this happen. After a short conversation with the questioner, if found that my solution was incomplete. Naturally, I started digging. What seems like it should be an otherwise mediocre task, has turned out to be a VERY-not-mediocre task. The short version is, WordPress simply does not want you to insert extra parts of the url, in the middle or beginning of the url, on every url. You can easily do this with post urls ONLY with the above code, but anything more (pages, attachments, author pages, etc...) you must do something special. You can also add parts to the end of the url (endpoints), but even that is complicated.
I have worked with the WordPress rewriter extensively in the past and present, and I have what is considered Expert knowledge on the topic. Despite that, it still took me 4-5 hours to write something that will allow you to prepend a language indicator to all urls, that can then later be used to determine what language the page should be displayed in, regardless of page type. There is one catch, that I think is acceptable. You must know and specify exactly what language prefixes you want to support. I don't foresee this as a problem for anyone who would make use of this, but none-the-less, it is a limitation, simply because of the way that the rewrite engine works.
At long last, here is a plugin that you can use to accomplish this. I works on a barebone WP install, with a WooTheme as the theme. If you have other third party plugins installed, there is a possibility that this will not work for all their urls, depending on how they added their rewrite rules. In the short term, I will probably be converting this to a plugin for WP, and getting it up on Wordpress.org, but that is several days away, at least. Here is a working prototype of the code in plugin form. Create a new directory in your plugins folder (something like /wp-content/plugins/lou-lang), and then paste this code in a php file inside that folder (something like /wp-content/plugins/lou-lang/lou-lang.php). Then activate the plugin, via your admin dashboard, which will be labeled 'Loushou Language URLs'.
CODE:
<?php (__FILE__ == $_SERVER['SCRIPT_FILENAME']) ? die(header('Location: /')) : null;
/**
* Plugin Name: Loushou Language URLs
* Plugin URI: http://quadshot.com/
* Description: Adding the ability to have language support in your frontend urls.
* Version: 0.1-beta
* Author: Loushou
* Author URI: http://quadshot.com/
*/
class lou_rewrite_takeover {
protected static $add_rules = array();
public static function pre_init() {
// debug
add_action('admin_footer-options-permalink.php', array(__CLASS__, 'qsart_rewrite_debug'));
// add rw tag
add_action('init', array(__CLASS__, 'add_directory_rewrite'));
// rw rule adds
add_filter(is_admin() ? 'setup_theme' : 'do_parse_request', array(__CLASS__, 'do_parse_request'), 0);
add_filter('post_rewrite_rules', array(__CLASS__, 'post_rewrite_rules'));
add_filter('date_rewrite_rules', array(__CLASS__, 'date_rewrite_rules'));
add_filter('root_rewrite_rules', array(__CLASS__, 'root_rewrite_rules'));
add_filter('comments_rewrite_rules', array(__CLASS__, 'comments_rewrite_rules'));
add_filter('search_rewrite_rules', array(__CLASS__, 'search_rewrite_rules'));
add_filter('author_rewrite_rules', array(__CLASS__, 'author_rewrite_rules'));
add_filter('page_rewrite_rules', array(__CLASS__, 'page_rewrite_rules'));
add_filter('rewrite_rules_array', array(__CLASS__, 'final_rules_correction'), PHP_INT_MAX, 1);
// query vars
add_filter('query_vars', array(__CLASS__, 'add_lang_query_var'), 10, 1);
add_filter('request', array(__CLASS__, 'default_language'), 9);
// fix permalinks
$link_filters_needing_rewrite = array(
'post_link',
'post_type_link',
'page_link',
'attachment_link',
'search_link',
'post_type_archive_link',
'year_link',
'month_link',
'day_link',
'feed_link',
'author_link',
'term_link',
'category_feed_link',
'term_feed_link',
'taxonomy_feed_link',
'author_feed_link',
'search_feed_link',
'post_type_archive_feed_link',
);
add_filter('pre_post_link', array(__CLASS__, 'change_permalink_structure'), 10, 3);
foreach ($link_filters_needing_rewrite as $link_filter)
add_filter($link_filter, array(__CLASS__, 'rewrite_lang_in_permalink'), 11, 3);
}
public static function do_parse_request($cur) {
self::get_page_permastruct();
self::get_author_permastruct();
self::correct_extras();
return $cur;
}
public static function get_supported_langs() {
return apply_filters('lou-get-supported-languages', array(
'en',
));
}
public static function add_directory_rewrite() {
global $wp_rewrite;
$supported_languages = self::get_supported_langs();
add_rewrite_tag('%lang%', '('.implode('|', $supported_languages).')');
}
public static function unleadingslashit($str) {
return ltrim($str, '/');
}
public static function final_rules_correction($rules) {
global $wp_rewrite;
$new_rules = array();
$supported_languages = self::get_supported_langs();
$find = implode('|', $supported_languages);
$find_find = '#(?<!\()('.preg_quote($find, '#').')#';
$preg_node = str_replace('%%%', '(\d+)', preg_quote($wp_rewrite->preg_index('%%%'), '#'));
foreach ($rules as $k => $v) {
if (preg_match($find_find, $k)) {
$nk = preg_replace($find_find, '('.$find.')', $k);
$parts = explode('?', $v);
$index = array_shift($parts);
$pv = implode('?', $parts);
$pv = preg_replace_callback('#'.$preg_node.'#', function ($matches) use ($wp_rewrite) {
return $wp_rewrite->preg_index($matches[1]+1);
}, $pv);
$nv = $index.'?lang='.$wp_rewrite->preg_index(1).(!empty($pv) ? '&'.$pv : '');
$new_rules[$nk] = $nv;
} else {
$new_rules[$k] = $v;
}
}
return $new_rules;
}
public static function change_permalink_structure($struct) {
$struct = self::unleadingslashit($struct);
$struct = preg_replace('#^%lang%/?#', '', $struct);
return '/%lang%/'.$struct;
}
public static function extras_rewrite_rules($rules, $struct) {
global $wp_rewrite;
if ( is_array( $struct ) ) {
if ( count( $struct ) == 2 )
$new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct[0]), $struct[1] );
else
$new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct['struct']), $struct['ep_mask'], $struct['paged'], $struct['feed'], $struct['forcomments'], $struct['walk_dirs'], $struct['endpoints'] );
} else {
$new_rules = $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($struct) );
}
return $new_rules + $rules;
}
public static function post_rewrite_rules($rules) {
global $wp_rewrite;
// hack to add code for extras type urls (usually created by other plugins)
$func = array(__CLASS__, 'extras_rewrite_rules');
foreach ($wp_rewrite->extra_permastructs as $type => $struct) {
$filter = ($type == 'post_tag' ? 'tag' : $type).'_rewrite_rules';
add_filter($filter, function ($rules) use ($struct, $func) { return call_user_func_array($func, array($rules, $struct)); });
}
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->permalink_structure), EP_PERMALINK ) + $rules;
}
public static function date_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_date_permastruct()), EP_DATE) + $rules;
}
public static function root_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_date_permastruct()), EP_DATE) + $rules;
}
public static function comments_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->root . $wp_rewrite->comments_base), EP_COMMENTS, false, true, true, false) + $rules;
}
public static function search_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_search_permastruct()), EP_SEARCH) + $rules;
}
public static function author_rewrite_rules($rules) {
global $wp_rewrite;
return $wp_rewrite->generate_rewrite_rules( self::change_permalink_structure($wp_rewrite->get_author_permastruct()), EP_AUTHORS) + $rules;
}
public static function page_rewrite_rules($rules) {
global $wp_rewrite;
$page_structure = self::get_page_permastruct();
return $wp_rewrite->generate_rewrite_rules( $page_structure, EP_PAGES, true, true, false, false ) + $rules;
}
protected static function get_page_permastruct() {
global $wp_rewrite;
if (empty($wp_rewrite->permalink_structure)) {
$wp_rewrite->page_structure = '';
return false;
}
$wp_rewrite->page_structure = self::change_permalink_structure($wp_rewrite->root . '%pagename%');
return $wp_rewrite->page_structure;
}
protected static function get_author_permastruct() {
global $wp_rewrite;
if ( empty($wp_rewrite->permalink_structure) ) {
$wp_rewrite->author_structure = '';
return false;
}
$wp_rewrite->author_structure = self::change_permalink_structure($wp_rewrite->front . $wp_rewrite->author_base . '/%author%');
return $wp_rewrite->author_structure;
}
protected static function correct_extras() {
global $wp_rewrite;
foreach ($wp_rewrite->extra_permastructs as $k => $v)
$wp_rewrite->extra_permastructs[$k]['struct'] = self::change_permalink_structure($v['struct']);
}
public static function get_default_post_lang($post) {
return ( $lang = get_query_var('lang') ) ? $lang : 'en';
}
public static function rewrite_lang_in_permalink($permalink, $post=0, $leavename=false) {
// find the default post language via a function you have created to
// determine the default language url. this could be based on the current
// language the user has selected on the frontend, or based on the current
// url, or based on the post itself. it is up to you
$lang = self::get_default_post_lang($post);
// once you have the default language, it is a simple search and replace
return str_replace('%lang%', $lang, $permalink);
}
public static function add_lang_query_var($vars) {
// tell WP to expect the lang query_var, which you can then later use
$vars[] = 'lang';
// return the new list of query vars, which includes our lang param
return array_unique($vars);
}
public static function default_language($vars) {
if (array_diff( array_keys($vars), array('preview', 'page', 'paged', 'cpage') ))
$vars['lang'] = !empty($vars['lang']) ? $vars['lang'] : 'en';
return $vars;
}
public static function qsart_rewrite_debug() {
if (isset($_COOKIE['rwdebug']) && $_COOKIE['rwdebug'] == 1) {
global $wp_rewrite;
echo '<pre style="background-color:#ffffff; font-size:10px;">';
print_r($wp_rewrite->rules);
echo '</pre>';
}
}
}
if (defined('ABSPATH') && function_exists('add_action')) {
lou_rewrite_takeover::pre_init();
}
By default, the only language code supported by this plugin is 'en'. Obviously you need more than just that. Thus, once you have installed the plugin, you can add some code to your <theme>/functions.php file that looks something like this, to add the remainders.
function more_languages($list) {
$my_languages = array(
'de', 'zh', 'bg', 'fr'
);
return array_unique($list + $my_languages);
}
add_filter('lou-get-supported-languages', 'more_languages', 10, 1);
Once you have both installed the plugin and defined your custom languages, then you have one final step. You must save your permalinks. To do this from the admin, go to: Settings -> Permalinks -> Save Changes (button). After all of this, you should be good to go!
Hopefully this helps someone, and hopefully I can block out some time to get this up on wp.org.
The question is old but.. I was working on a lightweight solution for multi-language site and i came across the same problem. There is no easy way to do it with built-in WordPress functions. However (like mentioned by user1254824) there is a really easy trick to achieve it.
You can intercept the $_SERVER['REQUEST_URI'] global var, extract the /lang/ part and remove it before WordPress parsing. WordPress will serve you the regular page, but now you have your lang parameter in a var.
function localization_uri_process() {
global $lang; // then you can access $lang value in your theme's files
if( preg_match("%\A/([a-z]{2})/%", $_SERVER['REQUEST_URI'], $matches) ){
$lang = $matches[1];
$_SERVER['REQUEST_URI'] = preg_replace("%\A/[a-z]{2}/%", '/', $_SERVER['REQUEST_URI'] );
}
else
$lang = 'en'; // your default language
}
add_action( 'plugins_loaded', 'localization_uri_process' );
Then, you can also use filters to automatically rewrite all your links.
PS : The code need to be in a plugin. It won't work in your template php files.
I stumbled across this post while looking for a solution to put a language tag in front of the url path. While the wp_rewrite-solution is pretty much solid it kind of didn't work for my purpose (e.g. not having the language tag in front for the default language etc.).
So I took a closer look at the qTranslate-plugin and after I while I figured out that it uses a very simple and elegant solution:
Basically it does two things:
(Obviously) It changes all the Wordpress generated links (e.g. post_link, post_type_link, page_link etc.) to include the correct language tag in the url.
Instead of manipulating complex rewrite rules to have wordpress accept and correctly handle the language tag, it just hooks into "plugins_loaded" (that's right before Wordpress tries to parse the request) and manipulates $_SERVER['REQUEST_URI'] by cleaning out the language tag.
So if you e.g. call www.example.com/en/myurlpath Wordpress only "sees" www.example.com/myurlpath.
$_SERVER['REQUEST_URI'] = "/en/myurlpath" before the manipulation.
$_SERVER['REQUEST_URI'] = "/myurlpath" after the manipulation.
This way your only "job" is to clean up any urls before Wordpress is parsing them.

Wordpress match url for custom content without post or page

Im new in wordpress.
I want to use two tables and display some content without creating pages or posts.
The matched url will be something like this:
/[category]/[image] - /nature/green-tree
My method was to check the url in index.php from theme and split the url and create a mini route system just for the gallery. But I think it is not the smartest idea.
I don't want to use gallery plugins because I'm already using one, and this is a change that I need to to.
What is the best method to do this?
I suppose you need custom rewrite rules. Here is how you can do it by yourself.
If you are using a theme then open the functions.php file and enter the following code, otherwise if you are using a plugin, place this code somewhere in your plugin, but make sure, that it is loading immediately.
function registerCustomUrl($rewrite)
{
$rewrites = $rewrite->rules;
$newRewrites = array();
$newRewrites['([^/]+)/([^/]+)/?$'] = 'index.php?gallery_category=$matches[1]&gallery_image=$matches[2]';
foreach($rewrites as $rk => $rv)
{
$newRewrites[$rk] = $rv;
}
$rewrite->rules = $newRewrites;
}
add_action('generate_rewrite_rules', 'registerCustomUrl');
function registerCustomQueryVars( $vars ) {
$vars[] = 'gallery_category';
$vars[] = 'gallery_image';
return $vars;
}
add_filter('query_vars', 'registerCustomQueryVars');
function myCustomTemplateRedirect()
{
global $wp_query;
if(
isset($wp_query->query_vars['gallery_category']) &&
!empty($wp_query->query_vars['gallery_category']) &&
isset($wp_query->query_vars['gallery_image']) &&
!empty($wp_query->query_vars['gallery_image'])
)
{
// Within your custom template file you are able to
// use any theme function like the get_header(), get_footer(), etc
require_once('path/to/your/custom/template/file.php');
exit(0);
}
}
add_action("template_redirect", 'myCustomTemplateRedirect');

WP Oembed not passing through the “autoplay=1” variable

I'm having this problem.
I am passing this through a custom field here
(notice the "autoplay=1")
But when I load the video on my theme using wp_oembed_get... it displays the video fine, but it does not listen to the autoplay=1 variable I am passing through.
I need the videos to play on the load of the page.
I think the way to do it is using wordpress filters:
function modify_youtube_embed_url($html) {
return str_replace("?feature=oembed", "?feature=oembed&autoplay=1", $html);
}
add_filter('oembed_result', 'modify_youtube_embed_url');
This is my solution in functions.php
function embed_responsive_autoplay($code){
if(strpos($code, 'youtu.be') !== false || strpos($code, 'youtube.com') !== false){
$return = preg_replace('#embed/([^"&]*)#', 'embed/$1&showinfo=0&autoplay=1', $code);
return '<div class="embed-container">' . $return . '</div>';
}
return '<div class="embed-container">' . $code . '</div>';
}
add_filter( 'embed_oembed_html', 'embed_responsive_autoplay');
add_filter( 'video_embed_html', 'embed_responsive_autoplay' ); // Jetpack
Enjoy!
look up function wp_oembed_get and use the args to pass the autoplay... should work fine. Just paste in the url of the video not the &autoplay... you'll code that into the args part of the function.
So, after some research on this, the best way to do this is to leverage the oembed_fetch_url filter hook to add extra arguments to the oEmbed request URL. My specific goal was to allow an autoplay paramater, but this method is built to be easy to tailor to any oEmbed argument you need.
First, add this to your functions.php:
<?php
/**
* Add parameters to embed
* #src https://foxland.fi/adding-parameters-to-wordpress-oembed/
* #src https://github.com/WordPress/WordPress/blob/ec417a34a7ce0d10a998b7eb6d50d7ba6291d94d/wp-includes/class-oembed.php#L553
*/
$allowed_args = ['autoplay'];
function koa_oembed_args($provider, $url, $args) {
global $allowed_args;
$filtered_args = array_filter(
$args,
function ($key) use ($allowed_args) {
return in_array($key, $allowed_args);
},
ARRAY_FILTER_USE_KEY
);
foreach ($filtered_args as $key => $value) {
$provider = add_query_arg($key, $value, $provider);
}
return $provider;
}
add_filter('oembed_fetch_url', 'koa_oembed_args', 10, 3);
This function takes the generated oEmbed URL and its corresponding arguments and checks it agains a hard-coded list of whitelisted arguments, in this case ['autoplay']. If it sees any of these whitelisted keywords in the arguments passed to the oEmbed filter, it adds them with their given value to the oEmbed URL.
Then, all you need to do is add the oEmbed parameter to your shortcode in the Wordpress editor, like this:
[embed autoplay="true"]https://vimeo.com/1234567890/1234567890[/embed]
Be aware that the oEmbed class in WP uses the postmeta as a cache for these requests, so if you've embedded the target URL before, you might have to clear your postmeta cache in some way or add a cache buster of some kind to the target URL. If the link is in the cache, the filter hook will never get to run.
I hope this makes sense, as I feel like it's a pretty useful feature that's surprisingly hard to figure out how to achieve.
This can be easily fixed by modifying the wp_oembed_get() function in wp-includes/media.php to this:
function wp_oembed_get( $url, $args = '' ) {
// Manually build the IFRAME embed with the related videos option disabled and autoplay turned on
if(preg_match("/youtube.com\/watch\?v=([^&]+)/i", $url, $aMatch)){
return '<iframe width="560" height="315" src="http://www.youtube.com/embed/' . $aMatch[1] . '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe>';
}
require_once( ABSPATH . WPINC . '/class-oembed.php' );
$oembed = _wp_oembed_get_object();
return $oembed->get_html( $url, $args );
}

Categories