Skip to:
Content

Opened 3 years ago

Closed 2 years ago

#1647 closed defect (wontfix)

load_textdomain_mofile filter does not work

Reported by: pavelevap Owned by:
Milestone: 2.1 Priority: normal
Severity: normal Version: 2.0
Component: i18n/l10n Keywords: dev-feedback
Cc: pavelevap@…

Description

I needed special translation, so I created my own .mo file and tried to hook to load_textdomain_mofile filter to load my .mo file from my own plugin. Even if it works well with other plugins, bbPress does not work for me.

Attachments (2)

load_textdomain_mofile.patch (445 bytes) - added by pavelevap 2 years ago.
bbpress_mo_file.patch (476 bytes) - added by pavelevap 2 years ago.

Download all attachments as: .zip

Change History (20)

comment:1 pavelevap3 years ago

OK, I probably find the problem. File bbpress.php, public function load_textdomain(). This function returns true only when .mo file is in local or global directory. Other cases are not allowed, exactly load_textdomain() is not loaded and so load_textdomain_mofile hook does not work. It is not standard behaviour, textdomain should be loaded even if localization files are not available and allow using load_textdomain_mofile hook.

comment:2 cnorris233 years ago

  • Resolution set to invalid
  • Status changed from new to closed

You are correct in that bbPress only looks in the the bbp-languages or the wp-content/langauges folder. However, in the case of plugins, which aren't typically going to use either of those folders, then the burden is on the plugin to load the file. In order to load your custom mo file, you'll need to run a funtion like $bbp->load_textdomain() from within your own plugin.

Alternatively, if you're only changing a few strings, you may want to have a look at http://www.viper007bond.com/2011/07/13/changing-core-wordpress-strings/

comment:3 johnjamesjacoby3 years ago

  • Milestone Awaiting Review deleted

comment:4 pavelevap2 years ago

  • Milestone set to 2.1
  • Resolution invalid deleted
  • Status changed from closed to reopened

I created small patch to better explain logic of this issue. I need to use load_textdomain_mofile hook because there will be special forum translation for specific use which should be handled with plugin. But in this plugin, instead of simply using load_textdomain_mofile hook, I should have to check if bbPress is activated first, then check if textdomain is loaded and then use some kind of special functions like $bbp->load_textdomain() - and I am not sure how to do it the right way...

Is it possible to simple change a logic (as patch shows) or for example add apply_filter() to $mofile_local variable?

comment:5 cnorris232 years ago

Your patch would indeed fix your issue, but the problem is that it would run load_textdomain() for everyone, on every page load. The large majority of installations will be run in English, which means they have no need for load_textdomain(). Based on what you've said so far, my original comment stands. The burden is on your plugin. To do it right, you shouldn't even need the load_textdomain_mofile hook. All you should need to do is take the $bbp->load_textdomain() and customize it a little. Something like below:

function my_load_textdomain() { 
               // Allow locale to be filtered 
               $locale = apply_filters( 'bbpress_locale', get_locale() ); 

               // Do my conditions to find the correct mofile
               if ( my_conditions_are_met )
                       $mofile = the-mofile-i-need.mo;

               // Setup mofile path
               $mofile_path  = '/path/to/mofile/' . $mofile;  

               // Load the mofile
               if ( file_exists( $mofile_path ) ) 
                       return load_textdomain( 'bbpress', $mofile_path ); 

               // Nothing found 
               return false; 
}
add_action( bbp_load_textdomain', 'my_load_textdomain' );

Using the bbp_load_textdomain hook takes care of checking if bbPress is activated. This hook will only run when bbPress is activated. From there, you can check for the conditions you need, and load the appropriate mofile.

comment:6 pavelevap2 years ago

OK, thank you very much for clarifying, I did not notice bbp_load_textdomain hook.

Suggested function my_load_textdomain() should work. So, bbp_load_textdomain hook can be used for checking if bbPress is activated, but there is no check if "bbpress" textdomain was loaded before with default files or not? Or I can reload textdomain over? Sorry for bothering you, but I am not sure about the right way... It seems too complicated for me with many possible problems.

I created another patch (only idea). This approach could solve all previously mentioned problems. Textdomain will be loaded only when any .mo file exist and users can simply hook with their own .mo files. Thank you for feedback...

pavelevap2 years ago

comment:7 cnorris232 years ago

  • Keywords dev-feedback added

comment:8 johnjamesjacoby2 years ago

Why would you want to load a custom language for bbPress, and not for WordPress?

comment:9 follow-up: pavelevap2 years ago

I do not understand? I can load my own language files for WordPress with load_textdomain_mofile filter. But it is not simply possible to load my own language file for bbPress.

comment:10 in reply to: ↑ 9 cnorris232 years ago

But it is not simply possible to load my own language file for bbPress.

This is simply not true. You have been given instructions and code on how to load your own file. bbPress code is setup to load standard translation files found in standard locations. If you're looking to do something outside of the standard setup, which you are since you want the files in your plugin folder, then it is your plugin's responsibility to make this happen. Again, you been told how, and even given code to make this work.

comment:11 pavelevap2 years ago

You have been given instructions and code on how to load your own file.

Thank you for your code, but I have some more questions about it. Your code uses bbp_load_textdomain hook for checking if bbPress is activated, but is there any check if "bbpress" textdomain was loaded before with default files or not? Or I can reload textdomain over?

My example: bbPress will be automatically delivered and installed with default translation files and so they will be automatically loaded. But I want to use my own files independetly. So, I will call them from my plugin file and bbpress textdomain will be called twice? Sorry, but I am not professional programmer...

If you're looking to do something outside of the standard setup

No, I am strictly using WordPress Codex and standard functions. Using custom translation files is allowed in WordPress functions and I SIMPLY (easily) used STANDARD load_textdomain_mofile filter in several plugins without problems. bbPress is first one where I need to solve similar problems. I understand that there is no need to load textdomain for many English-speaking users, but when I want to use my custom translation files, there are some problems which are not SIMPLE for me and even your code does not solve all related issues.

And I am not the first who asks about similar problems: http://wordpress.stackexchange.com/questions/30555/how-to-keep-plugin-translates-after-updates

comment:12 johnjamesjacoby2 years ago

(In [3617]) Add traditional WordPress 'plugin_locale' filter to load_textdoman() method. See #1647.

comment:13 johnjamesjacoby2 years ago

(In [3618]) Update language path comment in bbPress::load_textdomain(). See #1647.

comment:14 johnjamesjacoby2 years ago

I commented on the Stack Exchange topic and here. I also just added the plugin_locale filter into bbPress 2.1 core, but doubt it will help with what you're trying to do. There is also already a filter on the bbPress $mofile, but no where are you trying to use it. Not to mention that bbPress is using load_textdomain() directly, so it does in-fact use 'load_textdomain_mofile' like you want it to.

I think the problem is more one of load order and execution. If you don't add your filters before bbPress has ran them, they will never process. Can you confirm that your code is even working the way you intend for it to?

Understand that writing plugins for plugins requires an extra set of logic to ensure that plugin is actually running. Otherwise you're running code for no good reason.

comment:15 cnorris232 years ago

@jjj, I think what pavelevap is saying is that he wants to use the 'load_textdomain_mofile' hook, but it's only loaded if if load_textdomain() is run, and load_textdomain() is only run if $bbp->load_textdomain can find a mo file in either the WP lang folder or the bbP lang folder. His files are located in *his* plugin folder, so $bbp->load_textdomain() doesn't run load_textdomain().

@pavelevap, even if you use the method outlined above, your code will essentially be the same as if you used the 'load_textdomain_mofile' hook. You only need two additional lines of code, and a different entry point, to get it done. Below is some updated code which makes sure that a mo file hasn't already been loaded. Anything besides unload_textdomain() and load_textdomain() is just there for sanity checks. You don't necessarily need them, and you can replace them with the code you would use in your function that is hooked to 'load_textdomain_mofile'.

function my_load_textdomain() { 
               // Make sure there's not other mo file loaded
               unload_textdomain( 'bbpress' );

               // Allow locale to be filtered 
               $locale = apply_filters( 'bbpress_locale', get_locale() ); 

               // Do my conditions to find the correct mofile
               if ( my_conditions_are_met )
                       $mofile = the-mofile-i-need.mo;

               // Setup mofile path
               $mofile_path  = '/path/to/mofile/' . $mofile;  

               // Load the mofile
               if ( file_exists( $mofile_path ) ) 
                       return load_textdomain( 'bbpress', $mofile_path ); 

               // Nothing found 
               return false; 
}
add_action( bbp_load_textdomain', 'my_load_textdomain' );

comment:16 cnorris232 years ago

@pavelevap Another way to do it would be like this:

function my_load_textdomain() { 
               global $bbp;

               // Allow locale to be filtered 
               $locale = apply_filters( 'bbpress_locale', get_locale() ); 

               // Do my conditions to find the correct mofile
               if ( my_conditions_are_met )
                       $mofile = the-mofile-i-need.mo;

               // Setup mofile path
               $mofile_path  = '/path/to/mofile/' . $mofile;  

               // Load the mofile
               if ( file_exists( $mofile_path ) ) {
                       remove_action( 'bbp_load_textdomain', array( $bbp, 'load_textdomain' ), 5 );
                       return load_textdomain( 'bbpress', $mofile_path ); 

               // Nothing found 
               return false; 
}
add_action( bbp_load_textdomain', 'my_load_textdomain', 4 );

comment:17 pavelevap2 years ago

@johnjamesjacoby: Thank you very much for your answer, I will also try to test my execution order.

Not to mention that bbPress is using load_textdomain() directly, so it does in-fact use 'load_textdomain_mofile' like you want it to.

Yes, but load_textdomain() function is not fired when there are no other translation files. And this situation can sometimes happen, so I must check activation, execution order, etc. When load_textdomain() function is loaded everytime, my problem would disappear. So I suggested patch with new filter to allow directly modifying $mofile_local path.

@cnorris23: Exactly! That was my initial problem. Thank you very much for your code samples, I will test it during weekend. I did not know unload_textdomain() function and now I can see also is_textdomain_loaded() conditional function in l10n.php file. I only wanted to do it the right way with simple standard hooks, but it is no problem when this solution also works well. Thank you very much!

comment:18 johnjamesjacoby2 years ago

  • Resolution set to wontfix
  • Status changed from reopened to closed

I see what you're saying. Until WordPress core allows plugins to stash their translations into subfolders in WP_LANG_DIR, this is a problem. That probably won't happen, as more work is going into GlotPress to automate the translation downloads instead. Long term goal is for zips to detect the locale of the install and bundle the appropriate translation as needed.

Note: See TracTickets for help on using tickets.