Multilingual LabelMaker

by Matthew Leering



LabelMaker Pro

This is my attempt at providing a simple, modular tool to FileMaker Pro developers that will translate all your field labels into the selected language.  It’s scalable, efficient, and much easier to use than any of the other solutions I’ve found that aim for the same goal.  Once implemented into your system, creating new labels is as easy as creating a new record, assigning it a variable name, and providing the various translations for it.

Try it out, let me know what you think, and definitely send any suggestions my way.  I’ll be happy to implement them.

Download –>


2014-07-07 –> Added a “Refresh All Windows” option as requested by Giedrius.  Windows are refreshed in reverse order so as to maintain consistent order

2013-11-18 –> Altered field definition for Labels::LabelsByLanguage – Field now has an auto-enter calc that will prohibit entry of double quotes.  It will replace them will single quotes (Double-quotes were breaking my call to Evaluate)


29 responses to “Multilingual LabelMaker”

  1. Dominguez says:

    Thank you very much for this solution. It is so far the best and easiest solution I’ve seen to handle different languages. However there is one issue that never appears in multilingual solutions, when you have to select data from a list, Is there any way to make them appear in the appropriate language without creating new relationships?

    • Matt Leering says:

      Glad to hear that you’re getting some good use out of it.
      As for your question… I’m assuming you’re referring to multi-lingual value-lists.
      I’ve successfully implemented multi-lingual value-lists before, but am unaware of any way to be able to accomplish this kind of functionality without creating new relationships.
      The approach that I took was actually quite similar to the one that’s described elsewhere on this site.
      Check out the post titled “Virtual Value List” for details on that approach.

  2. Benjamin Lee says:

    Hello – I’ve tested your solution in FM 12 which works amazingly well. I have an older solution that is in FM11 and I can’t seem to get it to load correctly. Do you happen to have a version for FM11 that you’ve created?

    • Hi Benjamin.
      Glad it’s working well for you.
      I don’t have a copy of this working in FM11, but there’s not really any v12-specific functionality present in this module, so it should be easy enough to port. I’ll make a rough draft, and send it your way.

  3. CST says:

    Matthew, this is the most intelligent thing I’ve seen in the last months. And it saves my life! Thank you very very much.

    • Thanks CST, that’s probably the best compliment I’ve had in the last months. 🙂

      • CST says:

        As I play around with my first multilingual solution, I stumble over a BiG problem: dynamic labels on tab panels!?
        Any suggestions, tipps, links or “modules” available?

        • Hi CST;
          I’ve actually got 2 suggestions.

          1) Use a textbox/merge variable instead of actually giving names to your tabs. This can be done by simply making the top of the text box higher on your screen than the actual tab control itself. Even though it’s not going to be a part of the tab control, it can still hang down over top of it.

          2) Submit dynamic tab naming as a feature request to FileMaker
          FileMaker Feature Requests

  4. Ron says:

    Hi Matt,
    Your Labels system really works well. Thank you for the idea and sharing it.
    The only problem remaining for me is that in order for my ‘compiled’ app to be distributed to users whose native language differs, I produce a ‘clone’ copy. (This puts the dates into the users calendar format for example) When I do this, my Labels table is goes from 130 records to zero!

    I guess I could compile a version for each language but I would rather not. Do you know of a work around?

    • That’s a tricky one Ron;
      If you didn’t need the date format reset, then I would’ve recommended setting up a script to empty out all the tables except for the labels instead of cloning. When you do need the date format reset though, cloning is most likely going to be necessary. In those cases, the best solution might be to export the labels records, clone, and then import the labels records. Is this how you’ve already been handling it?

      • Ron says:

        GREAT IDEA! Thanks.
        I have created a ‘lot’ of records in the Labels layout and have these thoughts:
        I put two buttons on the top of the Labels layout: 1) Sort by Variable and 2) sort by English. This allows me to quickly find any occurrence of a $$variable or Name.

        Second, the translated text fails to show if the text contains a ” mark. Once I figured this out, it is only a minor inconvenience to search the text and replaces ” with ‘. I am thinking that modifying the script with a substitute function would do the same thing …. without error.

        Your app is a life safer. Thank you very much!!!!


        • Hey Ron;
          Thanks for the feedback.

          I’ve made some quick changes to the database to automatically convert the double quotes into single quotes. Instead of making that change to the script however, I decided it might be best to use the substitute function within an auto-enter calc that replaces existing values:

          Substitute ( Self ; “\”” ; “‘” )

          Also, if you find the export/import that I suggested earlier becomes too complicated, another option we could explore would be moving the label definitions into a 2nd file. If you choose to take this approach, you would need to make sure that the scripts from this module remain in the main file however, as global variables are defined on a file-specific level.

  5. ron says:

    Hi Matt,
    Glad to see that you changed LabelMaster Pro to auto enter single instead of double quotes. That should make it a lot easier.

    However, I don’t ‘get’ which field you changed to be an auto enter calc?


  6. ron says:

    Never mind! I copied your auto enter calc but forgot to turn off auto ‘Do Not Replace Existing Value’. Duh…. Works like a charm. It surely will eliminate having to proof read every translation. Thank you very much! Ron

  7. CST says:

    Has anybody made some experiences with A LOT variables?
    I really love this approach. But if I continue with this, I guess I’ll have more than 3000 variables in my solution. Some translations are just labels, others are a few sentences (help, quickinfo or dialog).
    Will this have a noticeable effect on the overall database-performance or cause any other problems I should be aware of? What about hosted files?

    • Not sure how I missed this comment earlier, so I apologize for the late response. I’ve got ~2000 labels in one of my solutions, and other than the extra second it takes to load during system startup, I haven’t really noticed any performance degradations.

      Seeing as this is a few months later, have you had the chance to implement this in your solution with ~3000 labels?

  8. CST says:

    FileMaker 13 solved that issue 😉

  9. CST says:

    the “dynamic labels on tab panels” issue.

  10. Giedrius G. says:

    Hi Matthew,

    very good approach to Multilingual solutions. Find it very usefull… Thanks!

    I would like to suggest a little upgrade to the main script, thich will Refresh all opened windows. If you use a solution you usually open few windows and after changing the language you prefer updates in all windows.

    These script steps will update all the opened windows with chosen language:
    If [ValueCount ( WindowNames ( Get (FileName) ) ) > 1]
    Set Variable [$WindowList; Value: WindowNames ( Get (FileName) )]
    Set Variable [$WindowCount; Value: ValueCount ( WindowNames ( Get (FileName) ) )]
    Set Variable [$WindowCurrent; Value: Get ( WindowName )]
    Select Window [Name: GetValue ( $WindowList ; $WindowCount ); Current file )
    Refresh Window []
    Set Variable [$WindowCount; Value: $WindowCount – 1]
    Exit Loop If [$WindowCount = 0]
    End Loop
    Select Window [Name: $WindowCurrent; Current file]
    End If

    Best regards,

  11. Thomas says:

    Hi Matthew,

    thanks for your brillant solution! On FM 13 it works great. I now stumbled across the problem, that the global language variables don’t load in filmmaker go (13.0.5) Have you got an idea how to solve this problem?

    Thanks again for your contributions to the community.

    Regards, Thomas

  12. Thomas says:

    Hi Matthew,

    it’s me again. I just testet your file (Multilingual LabelMaker.fmp12) an it actually works on FM Go. I think I have done something wrong in my own solution ;-(

    Sorry for the overhasty question…

    Best regards, Thomas

    • No worries Thomas;
      Glad to hear that you’re getting some good use out of this module.
      I’ve only done some rudimentary testing of this module on FM Go, but I’ve yet to run into any problems with it. Are you able to elaborate as to what kind of symptoms you’re seeing?

      Also, since you claim that this is a problem with your implementation of this module, perhaps if/when we get this resolved, we can mention the problem and fix here too.


  13. […] 上のソリューションはMatthew LeeringのMultilingual LabelMakerも利用していて、そこではグローバル変数の名前と対応するテキストを以下のように保持しています。 […]

  14. Menno says:

    Hi Matt,
    the solution you provide here is actually nice, but I would expect a bit more flexibility. I don’t want to clutter up the list of variables, when a lot of field-labels are created.
    I use another solution (which is in many ways similar to yours btw) but uses a table without records with only global-text-field for the labels instead of the global-variables. Also the definitions of languages is a bit different from yours and maybe a little more flexible.
    The article I wrote on my blog is in dutch, so I won’t bother you with that, but the download is all enlish, so you may want to have a look at that:
    cheers, Menno

    • Thanks for the feedback Menno;
      This solution isn’t for everyone, you’re right.
      I don’t like the fact that this solution clutters up the data viewer with tons of variables either, but the way that I look at it is that this will have zero impact on the end-user of the system (how often do they use data viewer?). I also think that it’s easier to simply add a record for a new label than it is to create a new global field (I used to use the global field solution too). That being said, these are just my personal preferences. Also, I haven’t yet checked out the download you linked me to. Very curious about it, and will check it out soon.

      Thanks again, and best regards!

  15. Bado says:

    Hi Matt

    I think your solution is great, and very simple to implement.
    I have one question how would you export/import to get translated, say if you wanted to translate the 1000+ records from English as a master into a new language such as Spanish. The export feature does not support repetitions.

    • Hey there Bado;
      Thanks for the feedback, and great question!
      There are a couple of ways to do this I think.

      What I would probably recommend is to create some new calculation fields in your Labels table.
      They can be stored calcs that return text.

      You will want them to have a formula such as:
      GetRepetition ( labelsByLanguage ; 1 )

      Create one of these calcs for each language that you need to export, and then choose to export these calcs instead of my actual labelsByLanguage field.

      Hope This Helps;

  16. Vincent says:

    Hi Matt,
    maybe I am late but I saw your solution only yesterday.
    BTW, your solution is great and very easy to implement. I would say the easiest and simpler I have ever seen !
    I have a question, could it be adapted so that (instead of adding to a layout many variable fields $$etc… ) can be used actual fields ?
    Again, congratulations for your nice job !

    • Thanks Vincent. I’m glad you found it so easy to implement. You certainly can use fields instead of variables, however, I have found that doing so detracts from its elegance if you do that. Either you need to create new fields for each new translation, or you would need to work with a single field with many repetitions, and reference them by repetition number (which would quickly get pretty obscure).

      I’d like to use a single variable that contains a JSON object ultimately, alas I don’t know of a way to dereference a JSON object’s properties inside of a merge variable as of yet

Leave a Reply

Your email address will not be published. Required fields are marked *