Override a WordPress plugin translation file on load - wordpress

I'm using WordPress in french with the plugin The Events Calendar.
This plugin comes with a bundled french translation but it has some mistakes. I want to fix them but replacing the original file is a bad idea since it's gonna be replaced with the next update. I contacted the developer to submit a fix but it may take some time.
In the meantime, I would like to load a duplicate I did from my template directory. I already tried multiple things like:
load_plugin_textdomain( 'tribe-events-calendar', get_template_directory() . '/languages' );
Or with
add_filter('override_load_textdomain', …)
in my functions.php but it doesn't seem to work. The only thing I was able to do is disabling the load of the original translation file.
Is there any way to replace a plugin translation file on load? I use WPML too but in "Translate with .mo files" mode not in "Translate with WPML" so I can't change plugin translation on the fly. Maybe WPML can load my own translation of The Events Calendar?

You can add this few lines in your functions.php theme file
$text_domain = 'the-events-calendar';
$original_language_file = ABSPATH . DIRECTORY_SEPARATOR . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'the-events-calendar' . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'the-events-calendar-fr_FR.mo';
$override_language_file = ABSPATH . DIRECTORY_SEPARATOR . 'wp-content' . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . 'your-own-theme' . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'the-events-calendar-fr_FR.override.mo';
// Unload the translation for the text domain of the plugin
unload_textdomain($text_domain);
// Load first the override file
load_textdomain($text_domain, $override_language_file );
// Then load the original translation file
load_textdomain($text_domain, $original_language_file );
You'll have to replace the two file variables with the actual language file.
But we'll suppose that the french language file is in the plugin language folder and your override language file is in the language theme folder.
The idea is to :
Un load the language that has already been loaded automatically by WP
Load your override file first. This is important to load it first, because already defined translations will be skipped when you'll load another language file for this text domain (see WP core).
Load the original translation file, which will in fact load all the untranslated strings of the override file.
This works only with compiled mo file.
You can only add to your override file the few strings you want to override.

I am the author of the Transposh plugin,
Your answer actually is in the following four filters:
add_filter('gettext', ......, 3);
add_filter('gettext_with_context', ......, 3);
add_filter('ngettext', ......, 4);
add_filter('ngettext_with_context', ....., 4);
(Naturally, you need to add the function and the priority instead of the .....)
Those functions will get the strings and the domain, and you can use those to do functions like:
function gettext_filter($translation, $orig, $domain) {
if ($domain == 'plugin_domain') {
if ($orig == 'some text') {
return "some translation";
}
}
return $translation;
}

This solution uses wordpress's automatic loaders to override the plugin and doesn't need additional programming logic, instead it lets the CMS do the override.
Let's say you want to translate a plugin called my-plugin. A properly built plugin would have two translated files in the directory wp-content/languages/plugins/ called my-plugin-fr_FR.po and my-plugin-fr_FR.mo. (The locale fr_FR is just my example for French translation, it works respectively for other language translations).
If your plugin has this structure, the steps below will override the translations, if not you can try and see anyway:
Copy the .po and .mo files mentioned above into the directory wp-content/languages/my-plugin. If the directory doesn't exist, create it.
Edit the translation files as you wish and save them.

Related

Wordpress multisite separate media folders plus a shared media folder?

So, I have moved my wp-content folder (and renamed it), and renamed my uploads folder. I will end up having 60+ sites in this install eventually, and it was rather annoying to look inside "uploads/sites" and just see each one labeled with the site id #, which doesn't tell me anything about which site it belongs to. So I had found a function that allowed me to create new folders for each sub-site. And that's working great and all. But I would also like to have one folder with assets that can be shared across the network, instead of having to upload to the individual sites. In other words, I need BOTH the individual media folders, AND a universal assets folder. I suspect that the code I have for creating the named media folders may interfere somehow, but I'm not sure how to solve that. Any help will be appreciated. Following is my current function (which has been put into a plugin so it's not template-dependent).
Note: I feel like there's a better way to set the baseurl & basedir using the UPLOADS folder defined in config. But I couldn't figure out how to get that to work properly.
add_action('init', 'new_upload_filters');
function new_upload_filters(){
add_filter('upload_dir', 'new_upload_dir');
}
function new_upload_dir( $dirs ) {
$blog = get_current_blog_id();
$site = get_blog_details()->blogname;
$sitestrip = str_replace(' ', '', $site);
$sitespace = strtolower($sitestrip);
$dirs['baseurl'] = network_site_url( WP_CONTENT_URL . '/library' );
$dirs['basedir'] = WP_CONTENT_DIR . '/library';
$dirs['path'] = $dirs['basedir']. '/' . $sitespace;
$dirs['url'] = $dirs['baseurl']. '/' . $sitespace;
return $dirs;
}
This code results in a path for each sub-site of /primary-network-url.com/content-dir/library/blogname, which is great (though I'd still also like to have the images broken out by date within each blogname folder too, but that's less important).
In my mind, the ideal would be to have an item within the Admin/Media area for "Shared Images", like a separate category or something. Be able to upload items to that "shared images" area from the parent site, and then those are also available to the sub-sites (but only able to add or delete those from the super admin).
Is this even reasonably possible?

rename() not working Wordpress plugin

I have a Wordpress plugin that will take the name of one directory on the server and rename to a name set in a Settings/Options field. The code I'm using is:
$base = basename(dirname(__FILE__));
$path = (isset($xgeneral['obf_plugin']))
?$xgeneral['obf_plugin']
:'original_directory';
if ($path != $base) {
$former = $base . DIRECTORY_SEPARATOR . 'mig_plugin.php';
$newer = $path . DIRECTORY_SEPARATOR . 'mig_plugin.php';
rename($former,$newer);
}
So what happens is when the plugin loads the first time, it checks if the obf_plugin option is the same as the directory in question; if they are different, it then renames it.
However, no matter what I try I get the error rename(migratex/mig_plugin.php,tango/mig_plugin.php): no such file or directory (tango is just the dumb sample word I tried to use) I tried referencing the absolute file path on the server using this code:
define("DS","/",true);
define('BASE_PATH',realpath(dirname(__FILE__)).DS,true);
but that doesn't make a difference.
Is there any reason why the rename() function is not working? It is running inside the Wordpress Admin page.
Thank you!
EDIT: Further investigation reveals this works in plain PHP but will not when running in Wordpress. Any thoughts as to how to enable rename() in Wordpress?

WordPress plugin localization, load_plugin_textdomain doesn't work

Ok i built plugin for contact form, I wanna add translation for it. In my main plugin files i add this code
function ap_action_init() {
// Localization
load_plugin_textdomain('prijava_forma', false, dirname(plugin_basename(__FILE__))."/languages";
}
// Add actions
add_action('init', 'ap_action_init');
in my file where contact form is written i have this
_e( 'Prva','prijava_forma' );
In my language folder I added the .mo and .po files created with Poedit.
Also I defined WPLANG in config.php and changed the language in the dashboard.
But i get no translation. Where could be problem, i am new to this?
There are many possible causes:
.mo file not readable or not found at all (.po file is not used by WordPress by the way)
The string you are expecting is not translated yet
Wrong .mo file name, valid names are ar.mo, fr_FR.mo..., invalid ones are br_BR.mo, arabic.po, AR.mo, ar_AR.mo... So make sure you get this one right.
for plugins the name will be the concatenation for the text domain, a dash and the locale: myplugin-ru_RU.mo
Check what load_plugin_textdomain() returned, if the .mo file was loaded, it should return true, in which case the next step would be to check that you are not missing the textdomain parameter in your __(), _e() and similar functions.
More on WordPress localization
It may be also caused on hook where the functions is attached and where are the po/mo files.
On the Init Hooks, load_plugin_textdomain() returned true but string were not translated.
I changed the action to plugins_loaded as my po/mo were in a folder inside a Custom plugins.
Also make sure that your string stands for itself. Do not append anything to the string, do this after the gettext function instead.
Wrong:
return __('Please translate me'.'(666)','your-textdomain');
Right:
return __('Please translate me','your-textdomain').'(666)';

Wordpress : load_textdomain won't load my .mo file (not for a theme nor a plugin but for a template part)

I am using Yoast's method to build an html site map in my Wordpress site. But it needs to be translated.
It uses a page template page-sitemap.php that uses a template part
<?php get_template_part('/partials/sitemap'); ?>
In this template part i ...
load_textdomain( 'site-map', TEMPLATEPATH.'/partials/languages' );
The function returns a false. (" If .mo file is not readable or the import fails - returns false. Otherwise returns true. ")
The path is right for I list the files of the folder TEMPLATEPATH.'/partials/languages' and it shows my language files.
As you see my domain name is 'site-map'. My .mo file is site-map-fr_FR.mo
Why can't it be loaded ?
Thanks for any clue,
nicolas
I found the answer :
load_textdomain( 'site-map', TEMPLATEPATH.'/partials/languages' );
... gives the path of the folder containing the .mo file. but the path of every individual mo file should be used in its own oad_textdomain instruction :
load_textdomain('site-map', TEMPLATEPATH.'/partials/languages/site-map-fr_FR.mo');
load_textdomain('site-map', TEMPLATEPATH.'/partials/languages/site-map-en_US.mo');
load_textdomain('site-map', TEMPLATEPATH.'/partials/languages/site-map-es_ES.mo');
load_textdomain('site-map', TEMPLATEPATH.'/partials/languages/site-map-ru_RU.mo');
load_textdomain('site-map', TEMPLATEPATH.'/partials/languages/site-map-de_DE.mo');
Shame on me it is a very obvious and useless thread ...
Sorry !
Try load_theme_textdomain('site-map', TEMPLATEPATH.'/partials/languages'); instead your function.

Getting path to Drupal root while in module

I am not sure if this is an issue with my current setup, or what I want to do.
I have a module that is programatically creating nodes in my Drupal 6 site, and within each I have to provide links in between various nodes.
I basically have a few foreach loops, and within each I have the current path.
For instance:
foreach ($page->category as $category) {
$category_link = "category/" . $category['id'];
// generate category pages
...
$content = "<a href='$category_link'>".$category['name']."</a>";
_create_node($content);
foreach ($category->article as $article) {
$article_link = $category_link . "/article/" . $article['id'];
// generate article page
$content = "<a href='$category_link'>".$category['name']."</a>";
$content .= "<a href='$article_link'>".$article['name']."</a>";
_create_node($content);
}
}
The issue that I'm seeing is that the link seems to be continually built up.
For instance, in the main category pages it is fine (I'll see category/1234), and the article link will be fine, but the category link will seem to be longer than it should. Basically, I'll end up seeing:
category/1234/article/5678/category/1234
My first thought was to make use of $base_url and just create absolute paths, however whenever I try printing that variable from my module it is completely empty. This is on a local server, however when I move it to production Drupal isn't installed at the root, so I can't simply add a slash to the front of the link.
Try using $GLOBALS['base_path'] to get the base path.
$GLOBALS['base_path'] will work, but you are accessing a global variable that ALSO contains some things like your database connection info and some other important stuff. So with a slip of the finger you could muck up other things. I prefer base_path() which does the same thing but is a modicum safer.
Use
global $base_url;
For path to themes folder use
path_to_theme()
You can use base_path() but that will not provide you with the domain name.
Base url will provide you the complete url like : www.example.com
base_path() will give you : /
path_to_theme() will give you : sites/all/themes/yourthemename

Resources