►
From YouTube: Hacksgiving: Internationalization Demo / Q&A
Description
In this session Daniel covers some tips/practices for making an internationalized Jenkins plugin
More info here: https://wiki.jenkins-ci.org/display/JENKINS/Internationalization
A
All
right
is
the
thing
on:
it
is
okay,
so
I'm
just
writing
a
little
plugin
today.
A
B
A
I,
just
can't
have
other
chickadees
alright,
so
we
have
strings
in
Java
and
we
have
strings
in
resources
and
they
have
to,
and
we
have
help
files
essentially
and
those
have
slightly
different
solutions
and
I'll,
just
showcase
them
here
all
right,
so
just
an
overview
of
what
the
plug-in
does.
The
idea
is,
let
me
see
whether
I
can
met
I
managed
to
share
a
browser
window
that
isn't
too
messy.
A
Alright,
so
this
is
a
browser
window
with
the
plug-in
running.
What
it
does
is.
It
adds
a
section
to
the
job
configuration
where
you
can
enable
adding
the
changelog
to
the
build
environment
variables,
and
there
are
three
options
here:
one
is
how
to
format
the
overall
entry
with
the
author
info
and
date,
information,
as
well
as
the
commit
ID
or
revision
and
the
commit
message
and
as
part
of
the
form,
validation,
I'm,
providing
a
sample
output
here.
A
The
author
words
to
commit
message,
as
well
as
which
files
are
affected
and
in
what
way
were
they
affect
it,
where
they
added
where
they
did
were
they
delete
it,
and
this
is
basically
what
this
second
form
field
allows
you
to
configure
how
this
looks
so
maybe
I
want
to
have
a
nicer
form
item
here
or
explicitly
say
the
action
was
this
and
the
file
path
is
this,
so
pretty
straightforward
and
the
last
form
field
allows
you
to
provide
the
date
form
it
to
be
used
in
the
overall
commit
information.
A
So
this
is
what
the
plug-in
does
you
can
see.
It
has
a
few
strings
that
are
currently
in
English
and
what
I'll
do
next
I
will
prepare
the
plug-in
for
localization
and
afterwards
try
to
localize
it
in
German.
Let's
see
how
well
that
goes.
It's
my
native
language,
but
I'm
using
all
of
myself
an
english.
So
that's
probably
pretty
terrible.
A
There
it
is
alright,
so,
let's
start
with
strings
in
code,
actually
I
already
prepared
that.
So
that's
just
unbelievable.
A
A
Since
everything
is
hard-coded,
I
also
have
no
way
if
I'm
a
contributor
who
knows
a
non-english
language,
to
just
provide
the
resources
needed
to
translate
this,
for
example,
into
german,
and
because
the
plug
in
right
now
is
fundamentally
not
set
up
to
be
localized.
So
we
will
need
to
change
this
first.
A
So,
let's
see
in
this
case
for
source
code
strings
the
way
to
resolve
this
is
to
create
a
file
called
msgs,
not
properties
in.
C
A
For
example,
in
this
case
the
display
name
and
what
I
do
then
is
I,
run
the
maven
target
localizer
generate
which
runs
the
localizer,
which
is
part
of
the
plug-in,
a
build
process,
and
if
I
do
that,
it
will
look
for
files,
called
messages
that
properties
and
generate
source
java
source
code
from
those,
and
we
can
take
a
look
here
and
see.
There's
a
new
class
named
messages
in
the
same
package,
and
this
is
what
will
support
localization
and
instead
of
returning
the
raw
and
translated
string.
A
Here
I
will
just
reference
messages,
class
and
the
method
by
the
name
of
the
key
I
just
added
to
the
resource
file
and
by
doing
that,
if
Jenkins
is
running
or
if
the
user
of
Jenkins
has
a
different
except
language
and
the
plug-in
has
a
matching
localization,
it
will
show
the
morning
list
string
and
we
can
do
basically
the
same
for
a
bunch
of
other
strings
here,
for
example,
let's
see
what
what
else
do
we
have
here?
I
mean
these
error.
A
Messages
will
be
printed
to
the
build
log
and
I
think
it's
always
a
bit
weird
to
have
them
in
a
different
language.
A
A
This
is
just
weird
so,
but
that's
my
personal
opinion
here,
sir
all
right.
So,
let's
see
that's
the.
A
Yeah
I
guess
we
we
can
translate
it
as
I
said
lower
priority,
it
doesn't
mean
you
don't
need
to
do
it.
So
all
right.
So,
let's
see
this
is
the
error
message
for
the
line.
Format,
error.
Let's
call
this
line
format,
error.
C
A
Have
the
same
string
as
entry
format
error,
because
we
have
three
separate
input
fields.
We
have
three
separate
possible
error
messages
and
the
last
one
is
the
date
format.
Error
I
can
use.
Basically
anything
I
want
as
a
ski
here
as
long
as
it
can
reasonably
translate
to
a
Java
identifier.
In
the
case
of
the
period,
you
will
see
that
this
will
get
replaced
by
an
underscore
when
I
access
that
static
field,
so
we
already
covered
this
one:
alright,
simple
output
and
something
after
it.
Let's
see
whether
I
can
manage
this
this
from
memory.
A
A
A
A
The
eight
format
sample,
of
course,
I,
could
have
done
on
the
easy
way
skip
the
placeholder
and
just
did
the
string
concatenation
here.
However,
that
would
have
failed
in
locales.
That
may
be
where,
where
the
prefix
Peter
colon
actual
example.
Well,
you
doesn't
work
as
well
as
in
English,
so
translators
have
more
flexibility
when
I
use
a
placeholder
like
this.
A
A
A
A
So
if
you
just
want
to
prepare
your
plug-in
for
localization,
you
can
do
this
and
you're
done.
However,
if
you're
actually
showing
a
more
complex
text
on
the
UI,
it's
useful,
of
course,
I.
Don't
have
something
like
that
here,
but
assuming
I
have
a
paragraph
of
stuff
here,
while
I
could
just
wrap
this
in
this
localization
marker.
A
A
If
I
do
it
like
this,
and
the
original
text
in
the
jelly
file
gets
changed,
it
will
no
longer
be
translated
into
German,
which
may
be
what
you
want.
However,
there's
a
better
approach
or
one:
that's
that's
common
in
Jenkins
core,
and
that
is
to
basically,
if
this,
a
very
generic
identifier.
So
if,
if
some
minor
part
of
the
string
changes,
you
would
have,
you
have
the
properties
file
which
is
English
or
the
default
translation,
and
you
have
a
config
underscore
de
properties
file
with
the
German
translation.
A
A
A
Why
is
that?
Because
I
forgot
to
escape
the
space
in
the
key
with
a
backslash
alright,
but
we
have
this
one
translated.
The
sample
output
is
still
in
English,
which
it
probably
should
not
be,
and
what
we've
also
not
translated
is
the
text.
Help
text
we
have
I
did
not
yet
do
that.
Alright,
let's
switch
back
to.
A
A
A
A
A
The
rest
here
is
in
English,
because
that's
directly
from
the
format
string
also
German
and
I
translated
the
date
format,
and
this
is
also
German,
so
everything
I
have
strings
reference
in
Java
code,
strings,
specified
in
jelly
resources
and
help
files
in
HTML
are
all
localizable
and
localized
into
German.
In
this
example,
here
any
questions.
A
A
Right,
let's
see
assuming
you
have
config
de
okay.
A
A
C
C
A
A
I
started
just
like
before.
What
you
can
do
here
is
with
this
format
string.
You
can
specify
parameters
like
this.
Basically,
when
you
saw
date,
format
one.
This
is
how
I
did
that,
and
what
you
can
also
do
in
this
expression
is
to
access
objects
that
have
been
injected
into
the
environment
and
excess
properties
of
those.
In
this
case,
I
can
just
print
the
full
name
of
the
current
project,
rather
than
a
property
of
this
build
wrapper
and
in
the
properties
file.
A
When
you
do
this,
you
will
also
need
a
english
translation,
because
otherwise
Jenkins
will
not
know
how
to
display
this.
So
what
I
did
was
I
defined
the
key
date
format
and
they'd
format
as
before,
and
then
in
parentheses,
the
placeholder,
for
whatever
I'm
trying
to
show
and
what
I
do
now
is
I
will
also
translate.
This
into
German
looks
exactly
the
same.
A
A
As
you
can
see,
this
is
the
German
localization
of
the
string
with
the
placeholder
getting
replaced
by
the
full
name
of
this
project.
So
this
is
how
you
insert
variables
here:
I'm,
actually
not
sure
what
happens
when
I
have
a
more
traditional
string
here.
Let
me
try.
This
may
work
it
may
not,
but
since
you
cannot
use
the
raw
string
here
without
any
translation,
it
doesn't
really
make
sense
to
make
it
look
nice
in
this
file.
So
let
me
reload
and
see
what
happens.
A
A
A
So,
for
example,
if
the
UI
shows
you
how
many
jobs
you
have
and
it's
like
a
number
jobs,
you
can
really
do
no
jobs,
401
job
for
one
or
n
jobs.
If
you
have
more
than
those
and
don't
have
to
do
something.
Weird
like
job
open
parenthesis,
zero,
close
parent,
open
s
close
because
you
don't
know
how
many
of
those
you
have.
B
B
So
let
me
look
at
the
time
means:
we've
got
two
and
a
half.
Oh
yeah,
I
second
Alexander's
a
request
to
push
this
code
somewhere,
even
if
it's
not
ready
to
be
to
be
published.
Yet.
B
A
Think
I'm
done
with
the
plugin,
so
I
need
another
idea:
I
mean
I,
haven't
tested
it
for
for
workflow,
but
otherwise
it
seems
to
work
fine,
more
or
less,
but
they'd
form
it
broke.
Just
no,
but
yeah
and
I
mean
who
needs
test.
So
I'm
really
done
here.
A
A
C
Okay,
again.
B
B
A
A
Something
specific
a
performance
issue,
or
what
are
you
asking
about
because,
most
of
the
time
when
I
used
a
groovy
script,
console
it's
not
debugging
or
look
finding
issues
of
some
kind,
but
more
like
I,
want
to
know
more
about
my
Jenkins
instance
and
build
statistics
of
some
kind.
So
what
kind
of
debugging
are
you
looking
for.
A
A
C
A
Execute
arbitrary
code
in
the
context
of
Jenkins,
which
can
be
really
powerful
and
really
dangerous,
I,
somehow
managed
to
convince
Jenkins
that
every
build
step
in
every
job
is
a
batch
file,
build
step
that
was
two
or
three
years
ago.
That
was
really
not
pretty
and
even
reloading
from
this
didn't
help
so,
and
that
was
the
production
instance,
so
you
should
be
C
really
really
careful.
C
C
A
In
general,
what
would
we
could
we
want
to
find
out
about
our
Jenkins
instance?
For
example,
in
an
instance,
I
had
I
was
responsible
for
for
a
few
years
until
I
changed
jobs.
A
One
of
my
key
once
was
to
prevent
the
proliferation
of
complex
job
configurations.
We
wanted
jobs
to
have
the
minimum
number
of
reasonably
possible,
build
steps
just
to
make
it
easier
to
investigate
things
and
reproduce
it
in
the
problems
independent
of
Jenkins,
and
we
wanted
any
scripts
that
are
longer
than
a
few
lines
to
be
stored
in
sem
and
once
more
than
a
few
dozen
people
start
configuring
stuff
on
your
jenkins
instance,
it's
not
enough
to
be
disciplined
yourself
or
within
your
team.
You
really
need
some
kind
of
tooling.
A
Right
very
basic
script,
which
just
prints
all
job
name,
so
I
have
a
single
job.
So
that's
not
too
interesting.
Let's
see,
I
want
to
find
all
jobs
that
use
my
incredibly
useful,
changelog,
annotation
I
just
wrote
so.
A
A
C
A
We
get
actually
get
a
map
here,
so
I
need
to
query
the
key
to
check
for
Rebecca.
This
is
equivalent
to
this
type
and
it
will
if,
if
basically
I'm
iterating
of
our
project,
then
I'm
iterating
over
all
build
wrappers
in
these
projects
and
it's
a
map
that
gives
me
a
map
entries,
basically
key
value
pairs
with
a
getter
get
key
and
I
compared
I.
Look,
whether
that
one
is
of
this
type
and
if
it
is
I
print
the
project
name.
C
A
A
This
is
basically
how
you
can
navigate
through
or
across
your
your
projects
and
find
out
information
about
your
champions
instance.
What
I
used
to
do
was
I
used
the
troubie
plugin.
For
this
you
could
also
use
scripture.
A
Whatever
out
would
I
had
a
high
appended
to
the
string
buffer.
A
It
looks
like
it
and
what
I
did
was
what
what
do
you
mean
by
global
glue,
groovy
scripts,
Christian.
A
A
Wanted
to
know
what
builds
were
configured
to
never
get
deleted.
I
wanted
to
know
what
drops
were
configured
to
keep
more
than
a
certain
number
of
builds,
and
what
you
can
do
is
with
the
groovy
plug-in
and
I'm,
not
entirely
sure
whether
it
was
a
good
idea
to
do
this,
but
I
did
it
anyway.
I
had
a
job
that
basically
checked
out
a
location
from
subversion.
It
will
respect
then,
and
this
and
then
had
a
system
groovy
build
step,
run.
A
A
Scripts
I
checked
out
from
sabor
shun
Soto
script
in
subversion,
had
access
to
the
entire
Jenkins
object
graph
and
generated
HTML
files
into
the
workspace
which
I
then
had
Jenkins
archive
and
allowed
me
to
browse
them.
So
in
that
way
it
was
centrally
defined,
but
if
you're
asking
whether
you
can
use
centrally
define
Ruby
scripts
with
the
script
console,
you
cannot
do
it
using
the
user
interface.
A
You
can
only
do
that
if
you
use
the
script
console
for
we
are
the
Jenkins,
remote
API
or
the
Train
can
see
a
lie
because
then
you
can,
just
you
know,
check
out
your
scripts
from
from
sem
and
have
a
batch
file,
execute
the
script
and
get
the
input
back.
If
you
click
the
see
a
lion
point,
you
can
see
here,
Maurice
it
groovy.
So
there's
the
groovy
CLI
command,
which
lets
you
execute
a
groovy
script,
and
this
groovy
script
will
also
have
access
to
all
of
the
Dinkins
of
tricks
and
everything.
A
A
And
this
plug-in
allows
you
to
manage
scripts
within.
Oh,
you
already
found
it
ok,
so
this
display
game
lets.
You
manage
scripts
in
Jenkins
and
run
those.
However,
compared
to
my
earlier
suggestion,
those
can
only
be
run
manually.
On
the
other
hand,
they
take
parameters
so,
depending
on
what
exactly
you
need
it's,
either
better
or
worse
than
then
what
I
had
just
suggested
earlier.
A
One
thing
of
note
here:
I
think
scripture
says
that
you
can
allow
users
to
run
a
script
if
they
have
the
run
scripts
permission.
Anyone
with
run
scripts
permission
can
run
arbitrary
scripts
in
your
tank
ins
instance.
This
is
an
even
more
powerful
permission,
then
administering
Jenkins,
because
administering
only
allows
you
what
you
are
allowed
to
do
on
the
UI.
If
you
can
run
scripts,
you
can
run
arbitrary
scripts.
So
this
is
a
bit
misleading
and
the
usual
matrix
authentication
plugin
on
my
threat.
Matrix
authorization
plug-in
UI
doesnt
help
with
this
either.
A
What
you
need
to
know
is
run
scripts
is
a
more
powerful
permission
than
administering
things.
So
it's
not
really
possible
to
use
this
to
make
these
scripts
available
to
users
without
giving
them
immense
power.
Over
your
Jenkins
instance,.