I struggle creating separate page feeds (list of URLs) in each language when WPML is active.
The plan is to have different feed names for each language, such as feed_name_en
or feed_name_fr
.
I wrote the following function that iterates through each available language on the site and should output a feed for each language containing only the pages in the particular language.
I found other examples that show how to pass parameters within add_action
using closures. (eg. add_action('init', function() use($param) { some_out_of_scope_function($param) } )
But in my function I am getting the following error:
Object of class Closure could not be converted to string in
I have the suspicion that it is because I am using OOP to encapsule the function in an array add_feed( $feedname, array( $this, ... ) )
. But I have no idea how to work around this.
How shall I approach this?
$feedname = 'feed_name'; private function createLanguageFeeds(){ foreach($this->wpml_languages as $lang){ // add the lang to the feed name. example: feed_name_en $feedname = $this->feedname . '_' . $lang; // making sure that the feed is created if ( ! in_array( $feedname, $wp_rewrite->feeds ) ) { $wp_rewrite->feeds[] = $feedname; flush_rewrite_rules( FALSE ); } add_feed( $feedname, array( $this, function() use ($lang) {$this->create_page_feed($lang);} ) ); } } private function create_page_feed($lang){ // echo pages }
Advertisement
Answer
If you’re using PHP 5.4 or newer, you can just pass the closure with the $lang
parameter to the add_feed()
function and $this
will retain the reference to the object:
add_feed( $feedname, function() use ($lang) {$this->create_page_feed($lang);} );
Note that your create_page_feed()
method needs to be public
so WordPress can access it:
public function create_page_feed($lang){ // echo pages }
(see What is the difference between public, private, and protected? for more details.)
Here’s a tested & working demo plugin that registers a feed using the Singleton pattern:
<?php /** * Plugin Name: Singleton RSS Feed * Plugin URI: https://cabrerahector.com * Description: A demo RSS feed built using the Singleton pattern. * Version: 1.0.0 * Author: Hector Cabrera * Author URI: https://cabrerahector.com/ * License: GPL-2.0+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt * Text Domain: singleton-rss-feed * Domain Path: /languages */ class Singleton_RSS_Feed { /** * The unique instance of the plugin. * * @var Singleton_RSS_Feed */ private static $instance; /** * Gets an instance of our plugin. * * @return Singleton_RSS_Feed */ public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } /** * Constructor. */ private function __construct() { // Actions add_action('init', array($this, 'createFeed')); } /** * Register the feed. */ public function createFeed() { global $wp_rewrite; $feedname = 'some_rrs_feed'; $lang = 'en'; // Making sure that the feed is created if ( ! in_array( $feedname, $wp_rewrite->feeds ) ) { $wp_rewrite->feeds[] = $feedname; flush_rewrite_rules( FALSE ); } add_feed( $feedname, function() use ($lang) {$this->renderFeed($lang);} ); } /** * Renders the feed. * * @param string $lang */ public function renderFeed($lang) { header( 'Content-Type: application/rss+xml' ); ?> <xml version="1.0" encoding="UTF-8"> <rss version="2.0"> <channel><title>RSS Feed in <?php echo $lang; ?> language</title></channel> </rss> <?php } } $Singleton_RSS_Feed = Singleton_RSS_Feed::get_instance();
The feed will be available here: https://www.example.com/feed/some_rrs_feed
.