4 #####################################################################
13 ## The component *.pot files are based roughly on CRM/Foo templates/CRM/Foo.
14 COMPONENT_POTS
="Admin Badge Batch Campaign Case Contribute Event Extension Financial Grant Mailing Member PCP Pledge Project Queue Report"
16 ## The adhoc *.pot files are based on clear file list (but may have some special/less predictable rules).
17 ADHOC_POTS
="common-base countries drupal-civicrm install menu provinces"
19 ## The magic *.pot files are derived from other *.pot files.
20 MAGIC_POTS
="common-components"
22 ## List of chosen *.pot files
25 ## Header file to prepend to any *.pot
26 HEADER_TMPL
=bin
/header
29 ## Flags to control which actions are performed
35 #####################################################################
38 create-pot-files.sh - builds .pot files for CiviCRM.
41 ./bin/create-pot-files.sh [options] [srcdir] [destdir] [pot1...]
44 ./bin/create-pot-files.sh ~/repository/civicrm/ ~/repository/l10n/po/pot/
45 ./bin/create-pot-files.sh -sd ~/repository/civicrm/ ~/repository/l10n/po/pot/ common-base Admin Contribute
48 -s Scan targets for strings (Pass #1)
49 -d Digest/dedupe scanned strings (Pass #2)
51 -a All (scan+digest+cleanup; default)
52 -f Force (Ignore cached results from previous scan)
57 $ADHOC_POTS $MAGIC_POTS
59 Although you should probably not call this directly. Use build-unified-pots.sh
60 if you are exporting the strings to Transifex.
61 http://wiki.civicrm.org/confluence/display/CRMDOC/Pushing+new+strings+to+Transifex
68 #####################################################################
69 ## Assert that CLI dependencies are met
70 function check_deps
() {
71 for cmd
in sponge civistrings msgcomm msguniq tempfile
tr grep cut
date sed ; do
72 if ! which $cmd > /dev
/null
; then
73 echo "Missing required command: $cmd"
77 echo 'This program uses the "sponge" command which you can get by installing the'
78 echo '"moreutils" package under Debian/Ubuntu or by visting'
79 echo 'https://joeyh.name/code/moreutils/'
82 echo 'This program uses the "civistrings" command which is bundled with buildkit.'
83 echo 'You can download it separately from https://github.com/civicrm/civistrings'
90 #####################################################################
91 ## civistrings wrapper with some default options
92 function _civistrings
() {
93 civistrings
--header="$HEADER" "$@"
96 #####################################################################
97 ## usage: HEADER=$(build_header "$HEADER_TMPL")
98 function build_header
() {
100 local out
="$POTDIR/.header"
101 local now
=`date +'%F %R%z'`
104 |
sed "s/NOW/$now/" \
110 #####################################################################
111 ## Build an individual POT file
112 ## usage: build_raw_pot <name>
113 ## example: build_raw_pot Mailing
114 ## example: build_raw_pot install
115 function build_raw_pot
() {
117 local filepath
="$POTDIR/.raw-"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
119 if [ -f "$filepath" -a -z "$FORCE" ]; then
120 echo "[[ Found raw strings for ${name} from previous scan. ]]"
124 echo "[[ Building raw strings for ${name} ]]"
128 ## Adhoc targets, sorted alphabetically
131 _civistrings
-o "$filepath" \
132 {CRM
,templates
/CRM
}/{ACL
,Activity
,Block
,common
,Contact
,Core
} \
133 {CRM
,templates
/CRM
}/{Custom
,Dashlet
,Dedupe
,Export
,Form
,Friend
} \
134 {CRM
,templates
/CRM
}/{Group
,Import
,Logging
,Note
,Price
,Profile
} \
135 {CRM
,templates
/CRM
}/{Relationship
,SMS
,Standalone
,Tag
,UF
,Utils
} \
136 xml
/templates
/civicrm_acl.tpl \
137 xml
/templates
/civicrm_data.tpl \
138 xml
/templates
/languages.tpl \
139 xml
/templates
/civicrm_msg_template.tpl \
140 xml
/templates
/message_templates
/friend_
* \
141 xml
/templates
/message_templates
/uf_notify_
* \
142 js
/angular-crmApp.js \
143 js
/angular-crmAttachment.js \
144 js
/angular-crm-ui.js \
148 js
/jquery
/jquery.crmeditable.js \
149 js
/jquery
/jquery.crmProfileSelector.js \
150 js
/jquery
/jquery.crmRevisionLink.js \
151 js
/jquery
/jquery.dashboard.js \
152 js
/model
/crm.designer.js \
154 js
/view
/crm.designer.js
155 packages
/HTML
/QuickForm \
156 partials
/crmAttachment \
157 partials
/crmExample \
161 ## The CRM/Upgrade folder includes *.tpl files which, for some reason,
162 ## have been omitted from past pot's. Omitting these requires more
163 ## precise file selection.
164 find CRM
/Upgrade
-name '*.php' | _civistrings
-ao "$filepath" -
165 _civistrings
-ao "$filepath" templates
/CRM
/Upgrade
169 ## Not yet; handled in the digest phase. That why it's in MAGIC_POTS
174 cat "$HEADER" > "$filepath"
175 grep ^INSERT xml
/templates
/civicrm_country.tpl \
177 |
while read entry
; do
178 echo -e "msgctxt \"country\"\nmsgid \"$entry\"\nmsgstr \"\"\n"
181 ## Hmm, if civicrm_country.tpl used {ts}, then we could just call "civistrings --msgctxt=country"
185 _civistrings
-o "$filepath" \
187 CRM
/Core
/Permission.php
191 _civistrings
-o "$filepath" \
196 cat "$HEADER" > "$filepath"
197 grep -h '<title>' CRM
/*/xml
/Menu
/*.xml \
198 |
sed 's/^.*<title>\(.*\)<\/title>.*$/\1/' \
199 |
while read entry
; do
200 echo -e "msgctxt \"menu\"\nmsgid \"$entry\"\nmsgstr \"\"\n"
203 _civistrings
--msgctxt=menu xml
/templates
/civicrm_navigation.tpl
-ao "$filepath"
207 cat "$HEADER" > "$filepath"
208 grep '^(' xml
/templates
/civicrm_state_province.tpl \
210 |
while read entry
; do
211 echo -e "msgctxt \"province\"\nmsgid \"$entry\"\nmsgstr \"\"\n"
214 ## Hmm, if civicrm_country.tpl used {ts}, then we could just call "civistrings --msgctxt=country"
217 ## Standard targets, sorted alphabetically
220 _civistrings
-o "$filepath" \
221 {CRM
,templates
/CRM
}/$name \
222 xml
/templates
/message_templates
/petition_
*
226 _civistrings
-o "$filepath" \
227 {CRM
,templates
/CRM
}/$name \
228 partials
/crmCaseType \
229 xml
/templates
/message_templates
/case_
*
233 _civistrings
-o "$filepath" \
234 {CRM
,templates
/CRM
}/$name \
235 xml
/templates
/message_templates
/contribution_
* \
236 xml
/templates
/message_templates
/test_
*
240 _civistrings
-o "$filepath" \
241 {CRM
,templates
/CRM
}/$name \
242 xml
/templates
/message_templates
/event_
* \
243 xml
/templates
/message_templates
/participant_
*
247 _civistrings
-o "$filepath" \
248 {CRM
,templates
/CRM
}/$name \
249 js
/angular-crmCaseType.js \
250 js
/angular-crmMailingAB.js \
251 js
/angular-crmMailingAB
/services.js \
252 js
/angular-crmMailing
/directives.js \
253 js
/angular-crmMailing.js \
254 js
/angular-crmMailing
/services.js \
255 partials
/crmMailing \
256 partials
/crmMailingAB
260 _civistrings
-o "$filepath" \
261 {CRM
,templates
/CRM
}/$name \
262 xml
/templates
/message_templates
/membership_
*
266 _civistrings
-o "$filepath" \
267 {CRM
,templates
/CRM
}/$name \
268 xml
/templates
/message_templates
/pcp_
*
272 _civistrings
-o "$filepath" \
273 {CRM
,templates
/CRM
}/$name \
274 xml
/templates
/message_templates
/pledge_
*
278 if echo " $COMPONENT_POTS " |
grep -q " $name " > /dev
/null
; then
279 _civistrings
-o "$filepath" {CRM
,templates
/CRM
}/$name
281 echo "unrecognized pot: $name"
287 find "$filepath" ! -empty |
while read f
; do
288 msguniq
"$filepath" | sponge
"$filepath"
292 #####################################################################
293 ## usage: make_stat <name>
294 ## example: make_stat Mailing
295 function make_stat
() {
297 local filepath
="$POTDIR/.raw-"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
298 grep ^msgid
"$filepath" |
sort -u > "$filepath.msgid"
299 grep '^#:' "$filepath" |
sed 's/#://' |
tr ' ' '\n' |
sort -u > "$filepath.files"
302 #####################################################################
303 ## Scan .raw-*.pot for common strings and put them in common-components.pot
304 ## usage: build_common_components
305 function build_common_components
() {
306 echo "[[ Building common-components.pot ]]"
309 for comp
in $COMPONENT_POTS ; do
310 local rawfile
=".raw-"$
(echo $comp |
tr '[:upper:]' '[:lower:]').pot
311 if [ -f "$rawfile" ]; then
312 paths
="$paths $rawfile"
316 if [ $has_multiple -eq 1 ]; then
317 msgcomm
$paths > .raw-common-components.pot
319 cat $HEADER > .raw-common-components.pot
323 #####################################################################
324 ## example: build_final_pot Mailing
325 ## example: build_final_pot install
326 function build_final_pot
() {
328 local rawpath
="$POTDIR/.raw-"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
329 local finalpath
="$POTDIR/"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
330 local tmpfile
=`tempfile`
332 echo "[[ Building final strings for ${name} ]]"
334 cp -f "$rawpath" "$finalpath"
336 if echo " $COMPONENT_POTS " |
grep -q " $name " > /dev
/null
; then
337 msgcomm
"$finalpath" .raw-common-components.pot
> $tmpfile
338 msgcomm
--unique "$finalpath" $tmpfile | sponge
"$finalpath"
340 msgcomm
"$finalpath" .raw-common-base.pot | sponge
$tmpfile
341 msgcomm
--unique "$finalpath" $tmpfile | sponge
"$finalpath"
343 elif [ "$name" == "install" ]; then
344 msgcomm
"$finalpath" .raw-common-base.pot | sponge
$tmpfile
345 msgcomm
--unique "$finalpath" $tmpfile | sponge
"$finalpath"
351 #####################################################################
353 function do_cleanup
() {
354 echo "[[ Cleanup temp files ]]"
355 rm .header .raw
*pot
-f
358 #####################################################################
361 [ "$1" == "--help" ] && usage
362 [ "$1" == "-h" ] && usage
367 while getopts "asfdc" opt
; do
391 echo "Invalid option: -$OPTARG" >&2
395 echo "Option -$OPTARG requires an argument." >&2
401 if [ -z "$FOUND_ACTION" ]; then
409 [ "$1" == "" ] && echo 'source dir missing' && usage
410 test ! -e "$1" && echo 'source does not exist' && usage
411 test ! -d "$1" && echo 'source not a directory' && usage
413 [ "$2" == "" ] && echo 'target dir missing' && usage
414 test ! -e "$2" && echo 'target does not exist' && usage
415 test ! -d "$2" && echo 'target not a directory' && usage
417 # use absolute paths so that we can chdir/pushd
418 SRC
=$
(php
-r 'echo realpath($argv[1]);' "$1")
419 POTDIR
=$
(php
-r 'echo realpath($argv[1]);' "$2")
420 HEADER
=$
(build_header
"$HEADER_TMPL")
421 ## TODO: substitute "NOW" in HEADER
425 POTS
="$COMPONENT_POTS $ADHOC_POTS $MAGIC_POTS"
430 if [ -n "$DO_SCAN" ]; then
431 pushd "$SRC" >> /dev
/null
432 for POT
in $POTS ; do
438 if [ -n "$DO_DIGEST" ]; then
439 pushd "$POTDIR" >> /dev
/null
441 build_common_components
442 for POT
in $POTS ; do
443 echo "+++++++++ $POT"
444 build_final_pot
"$POT"
449 if [ -n "$DO_CLEANUP" ]; then
450 pushd "$POTDIR" >> /dev
/null