Links on this page…

Plugins! feed.feed icon

TXP Plugins! is powered by Textpattern and most happily hosted by DreamHost.

Writing MLP-Ready Plugins.

Localised strings

If you want to allow users to edit your plugins’ strings using the string editing features of the new MLP Pack then you need to take a few extra steps to get your plugins into shape for the task.

Don’t worry, this will not make your plugins dependent upon the MLP Pack being present in an installation in order for it to work—it will work just fine without the MLP Pack.

Here are the steps…

  1. Have an internal array of named strings.
  2. Register a callback routine.
  3. Write your callback routine—copy the example routine from the code that follows changing details as needed. This will pass your array of strings to the MLP pack and register them as owned by your plugin.
  4. Write, or modify the example, plugin-specific gTxt() function that…
    1. tries to get the string from the $textarray and if that fails,
    2. tries to get the string from it’s private array and if that fails,
    3. returns the name of the string you were trying to access.
    4. does any variale substitutions that are needed
  5. Use the specific gTxt() function consistently throughout your pluign.

Here is an example you can use for study…

Listing 1: example_code
#Code
0001/*------------------------- PART 1: Define the strings -----------------------*/
0002 
0003#
0004# Define the string that will get prefixed to your strings when they are
0005# injected into the txp_lang table.
0006#
0007# Keep it less than 10 chars.
0008# Change both parts of the define for your plugins.
0009#
0010define( 'SED_EXAMPLE_PREFIX' , 'sed_xmpl' );
0011 
0012 
0013#
0014# Define the array of strings.
0015#
0016# Change the name and content of the array for your plugin.
0017# Variable substitutions will be done in your gTxt() routine, not here.
0018#
0019$sed_example_strings = array(
0020'string1' => 'Welcome {name}!',
0021'string2' => 'See you again {time}.',
0022);
0023 
0024 
0025 
0026/*------------------------ PART 2: Register A Callback -----------------------*/
0027 
0028#
0029# Register the callback for the enumerate string event.
0030# If the MLP pack is not present and active this will NOT get called.
0031#
0032register_callback( 'sed_example_enumerate_strings' , 'l10n.enumerate_strings' );
0033 
0034 
0035/*---------------------- PART 3: Registration Callback -----------------------*/
0036 
0037#
0038# Here's a callback routine used to register the above strings with
0039# the MLP Pack (if installed).
0040#
0041function sed_example_enumerate_strings($event , $step='' , $pre=0)
0042{
0043global $sed_example_strings;
0044$r = array (
0045'owner' => 'sed_example_plugin_name', # Change to your plugin's name
0046'prefix' => SED_EXAMPLE_PREFIX, # Its unique string prefix
0047'lang' => 'en-gb', # The language of the initial strings.
0048'event' => 'public', # public/admin/common = which interface the strings will be loaded into
0049'strings' => $sed_example_strings, # The strings themselves.
0050);
0051return $r;
0052}
0053 
0054/*--------------------- PART 4: Plugin Specific gTxt() -----------------------*/
0055 
0056function sed_example_gTxt( $what , $args = array() )
0057{
0058global $textarray;
0059global $sed_example_strings;
0060 
0061#
0062# Prepare the prefixed key for use...
0063#
0064$key = SED_EXAMPLE_PREFIX . '-' . $what;
0065$key = strtolower($key);
0066 
0067#
0068# Grab from the global textarray (possibly edited by MLP) if we can...
0069#
0070if(isset($textarray[$key]))
0071{
0072$str = $textarray[$key];
0073}
0074else
0075{
0076#
0077# The string isn't in the localised $textarray so fallback to using
0078# the string array in the plugin (which is not prefixed.)
0079#
0080$key = strtolower($what);
0081 
0082if( isset( $sed_example_strings[$key] ) )
0083$str = $sed_example_strings[$key];
0084else
0085#
0086# Fallback to returning the key if the string is not present...
0087#
0088$str = $what;
0089}
0090 
0091#
0092# If needed, perform substitutions...
0093#
0094if( !empty($args) )
0095$str = strtr( $str , $args );
0096 
0097return $str;
0098}
0099 

Download this code
[Copies Grabbed: 477]

Gettng Localised Data

The MLP Pack creates tables with localised content in them from the master textpattern table. The pack then uses a table-name remapping on the public interface to serve language specific content to plugins through the DB layer.

This remapping is not done on the admin side.

Although a language-specific temporary textpattern table could have been created to hide the original textpattern table for each client connection this would put a continuous un-needed load on the server so the MLP pack maintains a set of copies of the textpattern table—one table per site language— and then relies on a simple function to remap any queries against the ‘textpattern’ table to the copy with content in that language.

If your plugin uses any of the safe_blah() functions (except safe_query) or the fetch() routine; then this will happen without your needing to do anything special.

However, if your plugin accesses the textpattern table via a call to safe_query() or any of the other routines in txplib_db.php then it will work, but will potentially retreive rows for languages that the site visitor is not using.

To get around this you can make a few simple adjustments…

a) use the built-in DB access functions found in textpattern/lib/txplib_db.php rather than going to the DB via PHP’s MySQL access routines.

b) Don’t use the PFX constant.
Huh? Yes, if your plugin is meant for TxP 4.0.4 or above then this is easy as you can simply switch all PFX prefixing over to the safe_pfx() or safe_pfx_j() routines. The MLP Pack currently uses these to do some crafty table name changing to give access to localised content.

For plugins that need to work in TxP versions prior to 4.0.4 and you use the PFX constant then you can use the following routine to prefix your tables (and redirect to localised tables if the MLP Pack is present)...

Listing 2: example_code2
#Code
0001/*==============================================================================
0002 EXAMPLE CODE
0003 
0004Here is an example skeleton that meets the above requirements.
0005 
0006I am using the prefix sed_example_ here for my routines but you *must* change
0007that for your own plugins.
0008==============================================================================*/
0009 
0010function sed_example_pfx( $table )
0011{
0012if( is_callable( 'safe_pfx' ) )
0013$table = safe_pfx( $table );
0014else
0015$table = PFX.$table;
0016 
0017return $table;
0018}
0019 
0020(Remember to rename the function according to your plugin's naming convention).
0021 

Download this code
[Copies Grabbed: 455]

Now use this call whenever you need to construct the name of a table for a call to safe_query().

Or…

c) Try not to use the safe_query() routine but rather use the specific routines for the operations you are trying to perform (this is not possible for all queries)

For example, instead of doing…

safe_query( "select * from ".PFX."textpattern where `ID`='$my_id'" );

either use your prefix routine…

$table = sed_example_pfx( 'textpattern' ); safe_query( "select * from $table where `ID`='$my_id'" );

or use a more specfic access routine…

safe_row( '*', 'textpattern', "`ID`='$my_id'" );