Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Network: RU-Secure
Username: trsguest2017
Password: RUguest253$
Preparing a Plugin for
Translation
Brian Hogg
@brianhogg
brianhogg.com
echo esc_html( __( ‘Preparing
a Plugin for Translation’,
‘brian-hogg’ ) );
Courses 

https://brianhogg.com/courses
WordCamp Hamilton

https://hamilton.wordcamp.org/
Plugins

https://brianhogg.com/p...
Who Are You?
Why Translate?
How to Start?
<?php
/***
Plugin Name: Event Calendar Newsletter
Version: 1.6.1
Author: Brian Hogg
Author URI: https://brianhogg.com/
Lic...
<?php
/***
Plugin Name: Event Calendar Newsletter
Version: 1.6.1
Author: Brian Hogg
Author URI: https://brianhogg.com/
Lic...
Fetch a single event using the ID of
that event
__( ’Fetch a single event using the ID of
that event’, ‘event-calendar-newsletter’ );
_ _( $string, $textdomain )
__( ’Fetch a single event using the ID of
that event’, ‘event-calendar-newsletter’ );
_ _( $string, $textdomain )
__( ’Fetch a single event using the ID of
that event’, ‘event-calendar-newsletter’ );
_ _( $string, $textdomain )
__( ’Fetch a single event using the ID of
that event’, ‘event-calendar-newsletter’ );
_ _( $string, $textdomain )
Type thi...
// can’t do this
define( ‘ECN_TEXT_DOMAIN’, ‘event-
calendar-newsletter’ );
// ...
__( ’Fetch a single event using the ID
...
__( ’Fetch a single event using the ID of
that event’, ‘event-calendar-newsletter’ );
Right Way
echo __( ’Fetch a single event
using the ID of that event’,
‘event-calendar-newsletter’ );
Outputting the String
_e( ’Fetch a single event using
the ID of that event’, ‘event-
calendar-newsletter’ );
Outputting the String
_e === echo +...
What if you have
something you don’t want
translated?
Exclude a single event from the
listing. Use "current" when using the
shortcode on an event page to exclude
the current ev...
Exclude a single event from the
listing. Use "current" when using the
shortcode on an event page to exclude
the current ev...
__( ‘Exclude a single event from the
listing. Use "current" when using the
shortcode on an event page to exclude
the curre...
sprintf( __( ‘Exclude a single event
from the listing. Use "%s" when using
the shortcode on an event page to
exclude the c...
echo sprintf( __( ‘Exclude a single
event from the listing. Use "%s" when
using the shortcode on an event page to
exclude ...
Exclude a single event from the
listing. Use "current" when using the
shortcode on an event page to exclude
the current ev...
What if you want to
output HTML?
Can't find the option you're looking
for? <a href="https://mysite.com/
support">Submit a support request</a>
and we'll do ...
_e( "Can’t find the option you're looking
for? <a href="https://mysite.com/support
">Submit a support request</a> and we'l...
_e( "Can’t find the option you're
looking for? %sSubmit a support request
%s and we'll do our best to help!",
‘my-shortcod...
echo sprintf( __( "Can’t find the option
you're looking for? %sSubmit a support
request%s and we'll do our best to help!",...
Avoids link being
changed
Avoids broken HTML
Can’t find the option you're looking
for? %sSubmit a support request%s and
we'll do our best to help!
Sie können die gewünschte Option nicht
finden? %sSenden Sie eine Support-Anfrage
%s und wir werden unser Bestes tun, um zu...
Sie können die gewünschte Option nicht
finden? %sSenden Sie eine Support-Anfrage
%s <script>...</script>und wir werden
uns...
esc_html()
esc_attr()
Escape Functions
https://brianhogg.com/tips-sanitizing-validating-
wordpress-plugin-data/
esc_html( __( "blah blah blah
hahahaha", ‘my-shortcode’ ) );
Escape Functions
esc_html( __( "bla bla bla hihihihi”,
‘my-shortcode’ ) );
Escape Functions
esc_html( __( "bla bla bla <script>alert(‘test’);</
script> hihihihi”, ‘my-shortcode’ ) );
Escape Functions
esc_html( __( "bla bla bla <script>alert(‘test’);</
script> hihihihi”, ‘my-shortcode’ ) );
Escape Functions
bla bla bla &l...
Can Combine esc_html/
esc_attr and __/_e
Together
esc_html__()
esc_html_e()
esc_attr__()
esc_attr_e()
Escape Functions
echo esc_html( __( "blah blah blah
hahaha", ‘my-shortcode’ ) );
Escape Functions
echo esc_html( __( "blah blah blah
hahaha”, ‘my-shortcode’ ) );
Escape Functions
esc_html_e( "blah blah blah hahaha",
‘my-...
echo sprintf( esc_html__( "here is %smy link%s",
‘my-shortcode’ ), ‘<a href=“…”>’, ‘</a>’ );
Careful With sprintf
vs
esc_h...
here is my link
Careful With sprintf
vs
here is &lt;a href=“…”&gt;my link&lt;/a&gt;
wp_kses()
wp_kses_post()
Need HTML?
Plurals
_n( $single_string, $plural_string,
$number, $domain );
Plurals
_n( ‘you did one thing’, ‘you did lots
of things’, 1, ‘my-plugin’ );
Plurals
you did one thing
_n( ‘you did one thing’, ‘you did lots
of things’, 5, ‘my-plugin’ );
Plurals
you did lots of things
sprintf( _n( ‘you did %s thing’, ‘you did %s
things’, $count, ‘my-plugin’ ), $count );
Plurals
What if strings are similar
or hard to recognize?
__( ‘Read’, ‘my-plugin’ );
Adding Context
__( ‘Read’, ‘my-plugin’ );
_x( $string, $context, $domain );
Adding Context
_x( ‘Event Calendar Newsletter’,
‘Settings title’, ‘my-plugin’ );
Adding Context
_x( ‘Event Calendar Newsletter’,
‘Plugin ...
date_i18n()
Dates
date_i18n( get_option( 'date_format' ),
$timestamp )
Dates
JavaScript
wp_localize_script()
JavaScript
wp_register_script( ‘ecn_my_script’, plugins_url( ’js/
myscript.js’, __FILE__ ) );
wp_localize_script( ‘ecn_my_script’, ‘e...
Don’t trust the strings
in JavaScript
https://brianhogg.com/tips-sanitizing-validating-
wordpress-plugin-data/
Best Practices
Best Practices
• Decent English style
• Entire sentences
• Split at paragraphs
• Use format strings instead of string conc...
Now What?
Now What?
• Generate the POT file (base language)
• Copy to a PO file (for each translation)
• Generate the MO file (compi...
...
#: core/templates/admin-page.php:2 edd/edd.php:46
msgid "The Events Calendar Shortcode"
msgstr ""
#: core/templates/ad...
#: core/templates/admin-page.php:2 edd/edd.php:46
msgid "The Events Calendar Shortcode"
msgstr "The Events Calendar Shortc...
??6?I|????dD?
?Z?/!
Q,_Y?^?7E:}??UA"?n?O)	 Ey	?	 	 ?	 ?	 ?	 <
a@
?
?
?
??
Xv
|?
FLE?L?;&
-b
?
??
_LZ?^fjm~H??'?V 5w*?&????...
/languages
my-plugin.pot
my-plugin-fr_FR.po
my-plugin-fr_FR.mo
my-plugin-pt_BR.po
my-plugin-pt_BR.mo
...
Creating the Tran...
Creating the POT
POEdit
https://www.youtube.com/watch?v=s6oRk6nfkI0
makepot.php

svn co http://develop.svn.wordpress.org/t...
function my_load_textdomain() {
load_plugin_textdomain( ‘my-plugin', false,
plugin_basename( dirname( __FILE__ ) ) . '/lan...
Test by Switching to the
Language
Testing
Testing
Maintaining Over Time
Ensure Any New Strings
Wrapped in a Translation
Function
Automatic POT
Generation for wp.org
(free) Plugins
Translators Can Pull
Requests on github/
bitbucket
DEMO
Takes Work
Questions?
Des questions?
Questões?
¿Preguntas?
Brian Hogg
@brianhogg
brianhogg.com
https://brianhogg.com/wcto2017/
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Brian hogg   word camp preparing a plugin for translation
Upcoming SlideShare
Loading in …5
×
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

0

Share

Download to read offline

Brian hogg word camp preparing a plugin for translation

Download to read offline

You have a plugin, but you want users to be able to use it in their native language. Learn how to get it ready for translation, things to watch out for, and tips for maintaining it as you change the plugin over time.

Related Books

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Brian hogg word camp preparing a plugin for translation

  1. 1. Network: RU-Secure Username: trsguest2017 Password: RUguest253$
  2. 2. Preparing a Plugin for Translation Brian Hogg @brianhogg brianhogg.com
  3. 3. echo esc_html( __( ‘Preparing a Plugin for Translation’, ‘brian-hogg’ ) );
  4. 4. Courses 
 https://brianhogg.com/courses WordCamp Hamilton
 https://hamilton.wordcamp.org/ Plugins
 https://brianhogg.com/plugins Slides https://brianhogg.com/wcto2017/
  5. 5. Who Are You?
  6. 6. Why Translate?
  7. 7. How to Start?
  8. 8. <?php /*** Plugin Name: Event Calendar Newsletter Version: 1.6.1 Author: Brian Hogg Author URI: https://brianhogg.com/ License: GPL2 or later */
  9. 9. <?php /*** Plugin Name: Event Calendar Newsletter Version: 1.6.1 Author: Brian Hogg Author URI: https://brianhogg.com/ License: GPL2 or later Text Domain: event-calendar-newsletter */
  10. 10. Fetch a single event using the ID of that event
  11. 11. __( ’Fetch a single event using the ID of that event’, ‘event-calendar-newsletter’ ); _ _( $string, $textdomain )
  12. 12. __( ’Fetch a single event using the ID of that event’, ‘event-calendar-newsletter’ ); _ _( $string, $textdomain )
  13. 13. __( ’Fetch a single event using the ID of that event’, ‘event-calendar-newsletter’ ); _ _( $string, $textdomain )
  14. 14. __( ’Fetch a single event using the ID of that event’, ‘event-calendar-newsletter’ ); _ _( $string, $textdomain ) Type this out!
  15. 15. // can’t do this define( ‘ECN_TEXT_DOMAIN’, ‘event- calendar-newsletter’ ); // ... __( ’Fetch a single event using the ID of that event’, ECN_TEXT_DOMAIN ); Wrong Way
  16. 16. __( ’Fetch a single event using the ID of that event’, ‘event-calendar-newsletter’ ); Right Way
  17. 17. echo __( ’Fetch a single event using the ID of that event’, ‘event-calendar-newsletter’ ); Outputting the String
  18. 18. _e( ’Fetch a single event using the ID of that event’, ‘event- calendar-newsletter’ ); Outputting the String _e === echo + __
  19. 19. What if you have something you don’t want translated?
  20. 20. Exclude a single event from the listing. Use "current" when using the shortcode on an event page to exclude the current event. Using Placeholders
  21. 21. Exclude a single event from the listing. Use "current" when using the shortcode on an event page to exclude the current event. Using Placeholders
  22. 22. __( ‘Exclude a single event from the listing. Use "current" when using the shortcode on an event page to exclude the current event.’, ‘my-shortcode’ ) Using Placeholders
  23. 23. sprintf( __( ‘Exclude a single event from the listing. Use "%s" when using the shortcode on an event page to exclude the current event.’, ‘my- shortcode’ ), ‘current’ ); Using Placeholders
  24. 24. echo sprintf( __( ‘Exclude a single event from the listing. Use "%s" when using the shortcode on an event page to exclude the current event.’, ‘my- shortcode’ ), ‘current’ ); Using Placeholders
  25. 25. Exclude a single event from the listing. Use "current" when using the shortcode on an event page to exclude the current event. Using Placeholders
  26. 26. What if you want to output HTML?
  27. 27. Can't find the option you're looking for? <a href="https://mysite.com/ support">Submit a support request</a> and we'll do our best to help! Outputting HTML
  28. 28. _e( "Can’t find the option you're looking for? <a href="https://mysite.com/support ">Submit a support request</a> and we'll do our best to help!", ‘my-shortcode’ ); Outputting HTML
  29. 29. _e( "Can’t find the option you're looking for? %sSubmit a support request %s and we'll do our best to help!", ‘my-shortcode’ ); Outputting HTML
  30. 30. echo sprintf( __( "Can’t find the option you're looking for? %sSubmit a support request%s and we'll do our best to help!", ‘my-shortcode’ ), '<a href="https:// mysite.com/support">', ‘</a>' ); Outputting HTML
  31. 31. Avoids link being changed
  32. 32. Avoids broken HTML
  33. 33. Can’t find the option you're looking for? %sSubmit a support request%s and we'll do our best to help!
  34. 34. Sie können die gewünschte Option nicht finden? %sSenden Sie eine Support-Anfrage %s und wir werden unser Bestes tun, um zu helfen!
  35. 35. Sie können die gewünschte Option nicht finden? %sSenden Sie eine Support-Anfrage %s <script>...</script>und wir werden unser Bestes tun, um zu helfen!
  36. 36. esc_html() esc_attr() Escape Functions https://brianhogg.com/tips-sanitizing-validating- wordpress-plugin-data/
  37. 37. esc_html( __( "blah blah blah hahahaha", ‘my-shortcode’ ) ); Escape Functions
  38. 38. esc_html( __( "bla bla bla hihihihi”, ‘my-shortcode’ ) ); Escape Functions
  39. 39. esc_html( __( "bla bla bla <script>alert(‘test’);</ script> hihihihi”, ‘my-shortcode’ ) ); Escape Functions
  40. 40. esc_html( __( "bla bla bla <script>alert(‘test’);</ script> hihihihi”, ‘my-shortcode’ ) ); Escape Functions bla bla bla &lt;script&gt;alert(‘test’);&lt;/ script&gt; hihihihi
  41. 41. Can Combine esc_html/ esc_attr and __/_e Together
  42. 42. esc_html__() esc_html_e() esc_attr__() esc_attr_e() Escape Functions
  43. 43. echo esc_html( __( "blah blah blah hahaha", ‘my-shortcode’ ) ); Escape Functions
  44. 44. echo esc_html( __( "blah blah blah hahaha”, ‘my-shortcode’ ) ); Escape Functions esc_html_e( "blah blah blah hahaha", ‘my-shortcode’ );
  45. 45. echo sprintf( esc_html__( "here is %smy link%s", ‘my-shortcode’ ), ‘<a href=“…”>’, ‘</a>’ ); Careful With sprintf vs esc_html_e( sprintf( __( "here is %smy link%s", ‘<a href="…">’, ‘</a>’ ), ‘my-shortcode’ );
  46. 46. here is my link Careful With sprintf vs here is &lt;a href=“…”&gt;my link&lt;/a&gt;
  47. 47. wp_kses() wp_kses_post() Need HTML?
  48. 48. Plurals
  49. 49. _n( $single_string, $plural_string, $number, $domain ); Plurals
  50. 50. _n( ‘you did one thing’, ‘you did lots of things’, 1, ‘my-plugin’ ); Plurals you did one thing
  51. 51. _n( ‘you did one thing’, ‘you did lots of things’, 5, ‘my-plugin’ ); Plurals you did lots of things
  52. 52. sprintf( _n( ‘you did %s thing’, ‘you did %s things’, $count, ‘my-plugin’ ), $count ); Plurals
  53. 53. What if strings are similar or hard to recognize?
  54. 54. __( ‘Read’, ‘my-plugin’ ); Adding Context __( ‘Read’, ‘my-plugin’ );
  55. 55. _x( $string, $context, $domain ); Adding Context
  56. 56. _x( ‘Event Calendar Newsletter’, ‘Settings title’, ‘my-plugin’ ); Adding Context _x( ‘Event Calendar Newsletter’, ‘Plugin menu title’, ‘my-plugin’ );
  57. 57. date_i18n() Dates
  58. 58. date_i18n( get_option( 'date_format' ), $timestamp ) Dates
  59. 59. JavaScript
  60. 60. wp_localize_script() JavaScript
  61. 61. wp_register_script( ‘ecn_my_script’, plugins_url( ’js/ myscript.js’, __FILE__ ) ); wp_localize_script( ‘ecn_my_script’, ‘ecn_js’, array( ‘success’ => __( ‘You did the thing!’, ‘ecn’ ), ‘failure’ => __( ‘The thing didn’t work’, ‘ecn’ ), ) ); wp_enqueue_script( ‘ecn_my_script’ ); JavaScript https://brianhogg.com/jswp alert( ecn_js.success ); alert( ecn_js.failure );
  62. 62. Don’t trust the strings in JavaScript https://brianhogg.com/tips-sanitizing-validating- wordpress-plugin-data/
  63. 63. Best Practices
  64. 64. Best Practices • Decent English style • Entire sentences • Split at paragraphs • Use format strings instead of string concatenation— sprintf(__('Replace %1$s with %2$s'), $a, $b); is always better than __('Replace ').$a.__(' with ').$b; • Avoid unusual markup and unusual control characters • Do not leave leading or trailing whitespace in a translatable phrase https://codex.wordpress.org/ I18n_for_WordPress_Developers#Best_Practices
  65. 65. Now What?
  66. 66. Now What? • Generate the POT file (base language) • Copy to a PO file (for each translation) • Generate the MO file (compiled for quick string access) • Put them all in the languages/ folder of your plugin https://brianhogg.com/how-wordpress-org-plugin- translations-are-handled/
  67. 67. ... #: core/templates/admin-page.php:2 edd/edd.php:46 msgid "The Events Calendar Shortcode" msgstr "" #: core/templates/admin-page.php:4 msgid "" "The shortcode displays lists of your events. For example the shortcode to " "show next 8 events in the category "%s" in ASC order with date showing:" msgstr "" my-plugin.pot
  68. 68. #: core/templates/admin-page.php:2 edd/edd.php:46 msgid "The Events Calendar Shortcode" msgstr "The Events Calendar Shortcode" #: core/templates/admin-page.php:4 msgid "" "The shortcode displays lists of your events. For example the shortcode to " "show next 8 events in the category "%s" in ASC order with date showing:" msgstr "" "O shortcode mostra listas de seus eventos. Por exemplo, o shortcode para " "mostrar os próximos 8 eventos na categoria "%s", em ordem ASC exibindo a " "data:" my-plugin-pt_BR.po
  69. 69. ??6?I|????dD? ?Z?/! Q,_Y?^?7E:}??UA"?n?O) Ey ? ? ? ? < a@ ? ? ? ?? Xv |? FLE?L?;& -b ? ?? _LZ?^fjm~H??'?V 5w*?&??????vg??]2a ?6?_?V9<?F??e?)?y)k?_o ?(?@?g r????gL??V5S?X?I92? ???j?e?bS????T?!F+h^???83 .l ? /0()2!%3 my-plugin-pt_BR.mo
  70. 70. /languages my-plugin.pot my-plugin-fr_FR.po my-plugin-fr_FR.mo my-plugin-pt_BR.po my-plugin-pt_BR.mo ... Creating the Translations
  71. 71. Creating the POT POEdit https://www.youtube.com/watch?v=s6oRk6nfkI0 makepot.php
 svn co http://develop.svn.wordpress.org/trunk/tools/ grunt-wp-i18n https://github.com/cedaro/grunt-wp-i18n
  72. 72. function my_load_textdomain() { load_plugin_textdomain( ‘my-plugin', false, plugin_basename( dirname( __FILE__ ) ) . '/languages/' ); } add_action( 'plugins_loaded', 'my_load_textdomain' ); Load the Translations
  73. 73. Test by Switching to the Language
  74. 74. Testing
  75. 75. Testing
  76. 76. Maintaining Over Time
  77. 77. Ensure Any New Strings Wrapped in a Translation Function
  78. 78. Automatic POT Generation for wp.org (free) Plugins
  79. 79. Translators Can Pull Requests on github/ bitbucket
  80. 80. DEMO
  81. 81. Takes Work
  82. 82. Questions? Des questions? Questões? ¿Preguntas? Brian Hogg @brianhogg brianhogg.com https://brianhogg.com/wcto2017/

You have a plugin, but you want users to be able to use it in their native language. Learn how to get it ready for translation, things to watch out for, and tips for maintaining it as you change the plugin over time.

Views

Total views

1,511

On Slideshare

0

From embeds

0

Number of embeds

0

Actions

Downloads

1

Shares

0

Comments

0

Likes

0

×