WowAce.com Knowledge base

Repositories / Repository keyword substitutions

When repositories are packaged, certain keyword substitutions take place on text files.

Simple replacements

@file-revision@
Turns into the current revision of the file in integer form. e.g. 1234
Note: does not work for git
@project-revision@
Turns into the highest revision of the entire project in integer form. e.g. 1234
Note: does not work for git
@file-hash@
Turns into the hash of the file in hex form. e.g. 106c634df4b3dd4691bf24e148a23e9af35165ea
Note: does not work for svn
@project-hash@
Turns into the hash of the entire project in hex form. e.g. 106c634df4b3dd4691bf24e148a23e9af35165ea
Note: does not work for svn
@file-abbreviated-hash@
Turns into the abbreviated hash of the file in hex form. e.g. 106c63 Note: does not work for svn
@project-abbreviated-hash@
Turns into the abbreviated hash of the entire project in hex form. e.g. 106c63
Note: does not work for svn
@file-author@
Turns into the last author of the file. e.g. ckknight
@project-author@
Turns into the last author of the entire project. e.g. ckknight
@file-date-iso@
Turns into the last changed date (by UTC) of the file in ISO 8601. e.g. 2008-05-01T12:34:56Z
@project-date-iso@
Turns into the last changed date (by UTC) of the entire project in ISO 8601. e.g. 2008-05-01T12:34:56Z
@file-date-integer@
Turns into the last changed date (by UTC) of the file in a readable integer fashion. e.g. 20080501123456
@project-date-integer@
Turns into the last changed date (by UTC) of the entire project in a readable integer fashion. e.g. 2008050123456
@file-timestamp@
Turns into the last changed date (by UTC) of the file in POSIX timestamp. e.g. 1209663296
@project-timestamp@
Turns into the last changed date (by UTC) of the entire project in POSIX timestamp. e.g. 1209663296
@project-version@
Turns into an approximate version of the project. The tag name if on a tag, otherwise it's up to the repo.
:SVN returns something like "r1234"
:Git returns something like "v0.1-873fc1"
:Mercurial returns something like "r1234".

Debug replacements

These occur based on filetype, as they tend to tie into the comment system for the file.

The insides aren't removed so that line numbers stay the same, they just cause them to be commented out.

Lua

--@debug@ and --@end-debug@
Turns into --[===[@debug and --@end-debug]===].
--[===[@non-debug@ and --@end-non-debug@]===].
Turns into --@non-debug@ and --@end-non-debug@.

XML

<!--@debug@--> and <!--@end-debug@-->
Turns into <!--@debug and @end-debug@-->.
<!--@non-debug@ and @end-non-debug@-->.
Turns into <!--@non-debug@--> and <!--@end-non-debug@-->.

TOC

#@debug@ and #@end-debug@
Turns into #@debug@ and #@end-debug@, as well as adding a # to the beginning of each line in-between.

Exclude from packaging

These occur based on filetype, as they tend to tie into the comment system for the file.

--@do-not-package@ and --@end-do-not-package@ (for Lua)
<!--@do-not-package@--> and <!--@end-do-not-package@--> (for XML)
#@do-not-package@ and #@end-do-not-package@ (for TOC)
Removes everything between the @do-not-package@ and @end-do-not-package@ tags including the 2 tags themselves. This may cause line numbers of subsequent lines to change. The typical usage is at the end of Lua files surrounding debugging functions and other code that end users should never see/execute.

Because of pre-commit hooks, you will still need to comment out the @do-not-package@ and @end-do-not-package@ tags for the relevant file types.

Alpha replacements

These occur based on filetype, as they tend to tie into the comment system for the file.

The insides aren't removed so that line numbers stay the same, they just cause them to be commented out.

These occur from packages created not from tags, i.e. alpha packages.

This is useful to put extra debugging information that you want your alpha testers to have, but don't want to appear in release versions.

Lua

--@alpha@ and --@end-alpha@
Turns into --[===[@alpha and --@end-alpha]===].
--[===[@non-alpha@ and --@end-non-alpha@]===].
Turns into --@non-alpha@ and --@end-non-alpha@.

Example:

--@alpha@
assert(everythingIsOkay())
--@end-alpha@

This would make it so the assert takes place in dev mode and alpha zips, but doesn't bother for release and beta.

XML

<!--@alpha@--> and <!--@end-alpha@-->
Turns into <!--@alpha and @end-alpha@-->.
<!--@non-alpha@ and @end-non-alpha@-->.
Turns into <!--@non-alpha@--> and <!--@end-non-alpha@-->.

TOC

#@alpha@ and #@end-alpha@
Turns into #@alpha@ and #@end-alpha@, as well as adding a # to the beginning of each line in-between.

No-lib replacements

These occur based on filetype, as they tend to tie into the comment system for the file.

The insides aren't removed so that line numbers stay the same, they just cause them to be commented out.

These only occur on packages marked as -nolib.

TOC

#@no-lib-strip@ and #@end-no-lib-strip@.
Turn into #@no-lib-strip@ and #@end-no-lib-strip@, as well as adding a # to the beginning of each line in-between.

XML

<!--@no-lib-strip@--> and <!--@end-no-lib-strip@-->.
Turn into <!--@no-lib-strip and @end-no-lib-strip@-->.

Localization

If you've decided to use the localization app, you can inject the translations automatically with the following substitution:

@localization(locale="enUS", format="lua_table")@

or some derivation thereof.

The example turns into something that looks like { ["Some key"] = "Some value" }.

Arguments

Note: only locale and format are required.

locale
one of "enUS", "frFR", "deDE", etc. You'll see a full list of each possible locale on your project's localization page.
format
if "lua_table", then it will look like { ["Some key"] = "Some value" }
if "lua_additive_table", then it will look like L["Some key"] = "Some value"
handle-unlocalized - what to do when you have an unlocalized string.
if "english", then it will output the english value.
if "comment", then it will output the english value, but comment it out the line.
if "blank" (default), then it will output "", but comment out the line.
if "ignore", then no line will be printed out.
escape-non-ascii - whether to escape non-ASCII (unicode) strings as escape strings instead of raw UTF-8
if false (default), then you get a string like "Über"
if true, then you get a string like "\195\156ber"
prefix-values
This will prefix all value strings the given string. For WoW, the default is nothing. For WAR, since it is unicode-aware, its prefix is "L". e.g. "Hello" vs. L"Hello"
table-name - used in format="lua_additive_table" only.
This defines the name of the table to add to. For WoW, the default is "L". For WAR, the default is "T".
same-key-is-true
true - if the key is the same as the value, then make the value = true rather than the value itself.
false (default) - no special action when value == key.
namespace
"" (default) - the base namespace, all namespaces derive from this and phrases not attached to a namespace are on this base.
"Monkey" - the "Monkey" namespace. This varies based on your project.
"Monkey/Banana" - the "Monkey/Banana" subnamespace. This varies based on your project.
handle-subnamespaces
"none" (default) - don't show subnamespaces at all
"subtable" - show subnamespaces as a lua sub-table.
"concat" - concatenate the namespace with the key.
namespace-delimiter - used when handle-subnamespaces="concat"
"/" (default) - concatenate with / as the delimiter.
"." - use "." instead.
"any other string" - use "any other string" instead.

Example usage

Here's an example of AceLocale-3.0 usage with this new system:

enUS.lua

local debug = false
--@debug@
debug = true
--@end-debug@

local L = LibStub("AceLocale-3.0"):NewLocale("MyAddon", "enUS", true, debug)

--@localization(locale="enUS", format="lua_additive_table", same-key-is-true=true, handle-subnamespaces="concat")@

deDE.lua

local L = LibStub("AceLocale-3.0"):NewLocale("MyAddon", "deDE")
if not L then return end

--@localization(locale="deDE", format="lua_additive_table", handle-subnamespaces="concat")@

You're probably wondering about the @debug@ statement, but that's so that in development, you pass in an argument into :NewLocale that makes it so nonexistant translations don't error.

The resultant code will look like this:

enUS.lua

local debug = false
--[===[@debug@
debug = true
--@end-debug@]===]

local L = LibStub("AceLocale-3.0"):NewLocale("MyAddon", "enUS", true, debug)

L["Hello, World!"] = true
L["How are you today?"] = true
L["AwesomeModule/Eat some pie"] = "Eat some pie"

deDE.lua

local L = LibStub("AceLocale-3.0"):NewLocale("MyAddon", "deDE")
if not L then return end

L["Hello, World!"] = "Hallo, Welt!"
-- L["How are you today?"] = ""
L["AwesomeModule/Eat some pie"] = "Geh Kuchen essen"

You must login to post a comment. Don't have an account? Register to get one!

  • 10 comments
  • Avatar of Jakumi Jakumi Nov 25, 2012 at 11:13 UTC - 0 likes

    I added localization to my addon (wow) as @Morsker: Go described, however there seems to be a minor bug in curse's search result view. The tooltip on hovering my addon yields the unsubstituted version, though the toc-file in the zip-file is correct. don't know where to put it ...

    Last edited Nov 25, 2012 by Jakumi
  • Avatar of yukinoba yukinoba Sep 16, 2012 at 22:41 UTC - 0 likes

    Another question: How to assign "format" argument if I want to export with "Global strings"?

  • Avatar of yukinoba yukinoba Sep 16, 2012 at 22:35 UTC - 0 likes

    I've got a question: all my phrases (the "key" values in localization) has the same prefix, but it was deleted when I import it from file to wowAce localization app. Is there any way to add a prefix on the key using repository substitutions?

  • Avatar of Morsker Morsker Sep 09, 2012 at 17:04 UTC - 0 likes

    Localization can also be told to output 1 value at a time, which is useful in TOC files:

    ## Title-deDE: @localization(locale="deDE", key="Title", namespace="TOC")@
    ## Title-itIT: @localization(locale="itIT", key="Title", namespace="TOC")@
    ## Title-koKR: @localization(locale="koKR", key="Title", namespace="TOC")@

    Last edited Sep 09, 2012 by Morsker
  • Avatar of Flyhard Flyhard Sep 16, 2010 at 16:27 UTC - 0 likes

    the @debug@/@end-debug@ thing is quite nice - as long as you know what it is for.

    Basically, if you do plugin test locally without checking stuff in, the code enclosed is not commented away, but everything the packager build is without that code.

  • Avatar of dekimsey dekimsey May 03, 2010 at 22:58 UTC - 0 likes

    In reference to the localizer, always use double-quoted arguments. Not single-quotes. Single-quotes are not valid JSON.

    Otherwise you'll end up with an error somewhat like the following:

    • Error parsing value u'ruRU' in locales.lua: ValueError('No JSON object could be decoded',)
  • Avatar of Archarodim Archarodim Aug 26, 2009 at 09:43 UTC - 0 likes

    @file-timestamp@ and @project-timestamp@ don't work for GIT apparently... :/

  • Avatar of daxdax daxdax Aug 05, 2009 at 03:40 UTC - 0 likes

    Another handy way i've seen to deal with non-existant translations is to use a SetMetaTable() command. Setting the _Index handler to be a function to return the 'key' of the table if no value is found.

  • Avatar of StormFX StormFX Jun 07, 2009 at 21:33 UTC - 0 likes

    Just a note: the handle-namespaces attribute for localizations doesn't default to "none", it defaults to "concat". At least on the root...

  • Avatar of Nickenyfiken Nickenyfiken Jan 09, 2009 at 09:11 UTC - 0 likes

    Nice! Very neat to have. I have some suggestions. It would be great to have some best practices and examples that every addon "should" have.

    The only keyword I have added is "## Version: @project-version@" to the TOC. But I don't know if it is correct or not. It seems to be.

    I also think a separate KB for the localization app would be good. Really great so more authors should know how to use it.

  • 10 comments