Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Messages.po not filled by bash ./i18n.sh #11

Open
piejanssens opened this issue Aug 26, 2020 · 6 comments · May be fixed by #13
Open

Messages.po not filled by bash ./i18n.sh #11

piejanssens opened this issue Aug 26, 2020 · 6 comments · May be fixed by #13

Comments

@piejanssens
Copy link

piejanssens commented Aug 26, 2020

index.php

<html>
<body>
<h1>_('Hello World')</h1>
</body>
</html>

Structure:

  • index.php
  • locale
    -- en
    --- LC_MESSAGES
    ---- messages.po
    -- nl
    --- LC_MESSAGES
    ---- messages.po
    -- fr
    --- LC_MESSAGES
    ---- messages.po
➜  testlocales ls
composer.json composer.lock index.php     locale        vendor
➜  testlocales cd vendor/delight-im/i18n
➜  i18n bash ./i18n.sh NL                       
Extracting and updating translations
sed: 1: "locale/messages.pot": extra characters at the end of l command

I might be misinterpreting the functionality, but I was expecting 'hello world' to appear in the NL messages.po.

@piejanssens piejanssens changed the title Messages.po not filled by bash ./i18n Messages.po not filled by bash ./i18n.sh Aug 26, 2020
@ocram
Copy link
Contributor

ocram commented Aug 26, 2020

Thanks for your question and the perfect description of the problem!

The cause of this issue is that i18n.sh must be at the root of your project, at the same level as, or higher than, all your PHP source files. I see that this is not documented.

In order to solve the issue, you would thus have to replace your regular

cd vendor/delight-im/i18n

with a one-time

cp vendor/delight-im/i18n/i18n.sh .

to copy the script to your project’s root folder. But I understand that this may be undesirable, because it duplicates code and may force you to include the script in your project’s .gitignore – which would also force you to repeat the step of copying the script on every new machine.

Does that help?

Apart from that quick fix, the script certainly needs a parameter to specify which directory it should operate on.

@piejanssens
Copy link
Author

piejanssens commented Aug 27, 2020

Yes, progress.
I now see new text variables defined in index.php appear in a new locale/messages.pot file.
It doesn't make a difference if I do ./18n.sh nl-BEor ./18n.sh nl.

➜  testlocales ./i18n.sh nl   
Extracting and updating translations
sed: 1: "locale/messages.pot": extra characters at the end of l command
➜  testlocales 

@piejanssens
Copy link
Author

piejanssens commented Aug 27, 2020

I found the fix (for me). I removed the double quotes on lines 18, 23, 28, 46, 53
Fix for sed error: lmquang/til#18

@piejanssens
Copy link
Author

piejanssens commented Aug 27, 2020

Had to fix some more stuff. This is the script I ended up with.

  • Notice removal of double qoutes around variables with strings
  • Notice the explicit sed expression '' (see above)
  • Notice mkdir -p (--parent doesn't exist on macOS)
  • Notice commented lines for sed replace - I don't know how to fix this.
    sed: 1: "0,/\"Content-Type: text ...": bad flag in substitute command: '}'
#!/bin/bash

### PHP-I18N (https://github.com/delight-im/PHP-I18N)
### Copyright (c) delight.im (https://www.delight.im/)
### Licensed under the MIT License (https://opensource.org/licenses/MIT)

set -eu

# Switch to the directory where the current script is located
cd "${BASH_SOURCE%/*}" || exit 1

echo "Extracting and updating translations"

LOCALE_CODE="${1:-}"
LOCALE_PARENT_DIR="${2:-locale}"
LOCALE_DOMAIN="${3:-messages}"

if [ ! -d ${LOCALE_PARENT_DIR} ]; then
	echo " * Error: Target directory “${LOCALE_PARENT_DIR}” not found"
	exit 2
fi

if [ ! -w ${LOCALE_PARENT_DIR} ]; then
	echo " * Error: Target directory “${LOCALE_PARENT_DIR}” not writable"
	exit 3
fi

if [ -z ${LOCALE_CODE} ]; then
	echo " * Creating generic POT (Portable Object Template) file"
fi

find . -iname "*.php" -not -path "./vendor/*" | xargs xgettext --output=${LOCALE_DOMAIN}".pot" --output-dir=${LOCALE_PARENT_DIR} --language=PHP --from-code=UTF-8 --force-po --no-location --no-wrap --sort-output --copyright-holder="" --keyword --keyword="_:1,1t" --keyword="_f:1" --keyword="_fe:1" --keyword="_p:1,2,3t" --keyword="_pf:1,2" --keyword="_pfe:1,2" --keyword="_c:1,2c,2t" --keyword="_m:1,1t" --flag="_f:1:php-format" --flag="_fe:1:no-php-format" --flag="_pf:1:php-format" --flag="_pfe:1:no-php-format"
sed -i '' '/# SOME DESCRIPTIVE TITLE./d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
sed -i '' '/# This file is put in the public domain./d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
sed -i '' '/# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR./d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
#sed -i '' '0,/#, fuzzy/{s/#, fuzzy//}' "${LOCALE_PARENT_DIR}/${LOCALE_DOMAIN}.pot"
sed -i '' '/\"Project-Id-Version: PACKAGE VERSION\\n\"/d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
sed -i '' '/\"Report-Msgid-Bugs-To: \\n\"/d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
sed -i '' '/\"POT-Creation-Date: /d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
sed -i '' '/\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"/d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
sed -i '' '/\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"/d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
sed -i '' '/\"Language-Team: LANGUAGE <[email protected]>\\n\"/d' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
#sed -i '' '0,/\"Language: \\n\"/{s/\"Language: \\n\"/\"Language: xx\\n\"/}' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
#sed -i '' '0,/\"Content-Type: text\/plain; charset=CHARSET\\n\"/{s/\"Content-Type: text\/plain; charset=CHARSET\\n\"/\"Content-Type: text\/plain; charset=UTF-8\\n\"/}' ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"

if [ ! -z ${LOCALE_CODE} ]; then
	LOCALE_CONTENTS_DIR=${LOCALE_PARENT_DIR}"/"${LOCALE_CODE}"/LC_MESSAGES"

	mkdir -p ${LOCALE_CONTENTS_DIR}

	echo " * Creating PO (Portable Object) file for "${LOCALE_CODE}

	if [ -f ${LOCALE_CONTENTS_DIR}"/"${LOCALE_DOMAIN}".po" ]; then
		msgmerge --update --backup=none --suffix=".bak" --previous --force-po --no-location --no-wrap --sort-output "${LOCALE_CONTENTS_DIR}/${LOCALE_DOMAIN}.po" "${LOCALE_PARENT_DIR}/${LOCALE_DOMAIN}.pot"
	else
		msginit --input="${LOCALE_PARENT_DIR}/${LOCALE_DOMAIN}.pot" --output-file="${LOCALE_CONTENTS_DIR}/${LOCALE_DOMAIN}.po" --locale="${LOCALE_CODE}" --no-translator --no-wrap
		sed -i '' '/\"Project-Id-Version: /d' ${LOCALE_CONTENTS_DIR}"/"${LOCALE_DOMAIN}".po"
		sed -i '' '/\"Last-Translator: Automatically generated\\n\"/d' ${LOCALE_CONTENTS_DIR}"/"${LOCALE_DOMAIN}".po"
		sed -i '' '/\"Language-Team: none\\n\"/d' ${LOCALE_CONTENTS_DIR}"/"${LOCALE_DOMAIN}".po"
	fi

	echo " * Creating MO (Machine Object) file for "${LOCALE_CODE}

	msgfmt --output-file=${LOCALE_CONTENTS_DIR}"/"${LOCALE_DOMAIN}".mo" --check-format --check-domain ${LOCALE_CONTENTS_DIR}"/"${LOCALE_DOMAIN}".po"

	rm ${LOCALE_PARENT_DIR}"/"${LOCALE_DOMAIN}".pot"
fi

echo "Done"

@ocram
Copy link
Contributor

ocram commented Aug 27, 2020

Thanks for looking into this!

  1. Regarding the sed problem, the issue is that GNU sed (Linux) only supports sed -i and sed -i'', while BSD sed (macOS) only supports sed -i ''. There’s no way to make the syntax compatible with both standards.

    What we could do is use sed -i.bak and then remove the unneeded backup file, either after every call or once at the end.

    Another solution would be using sed on "$file" without the -i argument, redirecting the output to "$file.temp" every time, and renaming "$file.temp" to "$file" after every call, as with mv -- "$file.new" "$file".

  2. As for the “bad flag in substitute command” error, that’s because the syntax sed '0,/foo/{s/foo/bar/}' (to replace the first occurrence only) is specific to GNU sed as well. We would need a replacement that works on both systems.

  3. As for the removal of double qoutes around variables with strings, is that really necessary? Did you verify that it does not work without that (and only with the other solutions)?

  4. Replacing mkdir -p with mkdir --parents – sure, that would be fine.

An alternative solution for (1) and (2) would be to install GNU sed on macOS, e.g. via Homebrew (brew install gnu-sed).

@piejanssens
Copy link
Author

1+2: Completely OK with gnu-sed.
3: Just tested again after installing gnu-sed, no issues.
4. Yey!

@piejanssens piejanssens linked a pull request Aug 28, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants