TemplateTranslator – překladač pro šablony a formuláře

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
voda
Člen | 561
+
0
-

Diskuze k doplňku TemplateTranslator. Jedná se o gettextový překladač pro šablony a formuláře.

Doporučuji používat s vylepšeným NetteGettextExtractorem.

japlavaren
Člen | 404
+
0
-

Zdravim,

snazim sa o pouzitie Template Translator-u. Doteraz som getText nepouzil a neviem naist nikde pouzitelne riesenie – nastavim v nette vsetko ako ma byt, ale akym sposobom/kde vytvorim subor cs.mo a ako ho naplnim datamy?

voda
Člen | 561
+
0
-

Na to potřebuješ například GettextExtractor. Buď původní https://github.com/…xt-extractor nebo můj upravený https://github.com/…xt-extractor. Podívej se na odpovídající vlákno.

machina
Člen | 1
+
0
-

V subore TranslateMacros som musel riadok 57 upravit takto:

<?php
return $writer->write('echo %modify('.'$template->' . $prefix . 'gettext(' . $writer->formatArgs() . ')'.');');
?>

pretoze inak tento regularny vyraz jednoduche „%modify“ nezozral..

voda
Člen | 561
+
0
-

Díky za info, opravil jsem to a pushnul.
Jinak to bylo způsobeno commitem 0988ca74f88fffc8ea02.

Šaman
Člen | 2659
+
0
-

Ahoj. Mám připravit aplikaci na budoucí jednoduché překládání. Potřebuji vědět, jetli je možné mít některé řetězce i v PHP souborech, nebo vše, co se má přeložit musí být v šabonách? (V PHP mám např. labely formulářových inputů.)

A dají se překládat už předkompilované, nacacheované šablony?

Díky.

Patrik Votoček
Člen | 2221
+
0
-
  1. ano

u formulářů $form->setTranslator(ITranslator $translator);
u ostatních jak si to zařídíš ($translator->translate('foo') případně pokud si uděláš alias __('foo'))

  1. jasně {_'foo'} se totiž přeloží na $template->translate('foo')

pochopitelně musíš šabloně taky nastavit translátor $template->setTranslator(ITranslator $translator);

basovnik
Člen | 23
+
0
-

Ahoj, mám menší problém s rozchozením tohoto doplňku. Funguje mi, ale mám to napsaný dost prasácky. Je to způsobeno možná i tím, že jsem zatím nenašel takový návod, který by mě naučil pracovat s DI.

Translator k formuláři přiřazuji takto:

<?php
$translator = new \Antee\i18n\GettextTranslator($GLOBALS['params']['appDir'] . "/locale/" . $this->lang . "/messages.mo");
$form->setTranslator(new \Antee\i18n\NetteTranslator($translator));
?>

Funguje mi to, ale chtěl bych to rozjet přes:

<?php
$translator = $this->getContext()->getService('translator');
?>

Nevím ale, jak do config.neon dostat persistentní proměnnou presenteru $lang. V návodu je toto:

translator:
	class: Antee\i18n\GettextTranslator
		arguments:
		- %appDir%/locale/cs.mo" # cesta k souboru s překlady

Jak to jednoduše přeformulovat pro mé potřeby?

PS (offtopic):
Jak se elegantněji dostanu k proměnné appDir? Moje řešení $GLOBALS['params']['appDir'] myslím nejlepší není! :D

Děkuji!

voda
Člen | 561
+
0
-

Zatím mě nenapadá jak to tam hezky dostat, asi přidám metodu setCatalog().

K params by ses měl dostat přes $this->context->params.

basovnik
Člen | 23
+
0
-

@voda: Ta metoda se určitě bude hodit, ale bohužel to zatím neřeší můj problém, jak parametrizovat lang v neonu. Zatim budu rád, že to funguje a nebudu se v tom moc šťourat asi :) Dik

voda
Člen | 561
+
0
-

lang podle mě do contextu nedostaneš, protože ho máš v presenteru a v tu dobu už je context ‚frozen‘. Po přidání setCatalog metody by ale šlo v Presenter::startup udělat něco jako:

<?php
$params = $this->context->params + array('lang' => $this->lang);
$catalog = Nette\Utils\Strings::expand($params->catalogPath, $params);
$this->context->translator->setCatalog($catalog);
?>

Pokud někdo vymyslí něco lepšího, budu taky jedině rád.

basovnik
Člen | 23
+
0
-

Nakonec jsem z neonu service translator oddělal a do startupu v BasePresenteru jsem dal:

<?php
$catalogPath = $this->context->params['appDir'] . "/locale/" . $this->lang . "/messages.mo";
$this->context->addService('translator', new Antee\i18n\GettextTranslator($catalogPath));
?>

Pak už normálně používám např:

<?php
$translator = $this->context->getService('translator');
$form->setTranslator(new \Antee\i18n\NetteTranslator($translator));
?>

Co si myslíte o tomto řešení?

voda
Člen | 561
+
0
-

Přidal jsem metodu setCatalog.

Ještě mě napadlo, že by šlo zneužít toho, že proměnná $lang je v presenteru public, ale taky to není čistý řešení.

@**basovnik**:

<?php
$this->context->addService(...);
?>

to funguje? Jsem myslel že context je ‚frozen‘. Protože pokud není, tak můžeš do něj přidat parametr lang a v configu bys pak mohl mít:

- %appDir%/locale/%lang%.mo" # cesta k souboru s překlady
basovnik
Člen | 23
+
0
-

@voda: Mně ta má funguje. Frozen to nemám. Ta tvoje varianta je ale elegantnější. Zkusím to.

R@100
Člen | 2
+
0
-

Mozete mi spisat zaver z tohto, nejak sa mi nedari zmena jazyka za behu. Translator mi bezi ako servis nastaveny v neone.

voda
Člen | 561
+
0
-

R@100: Nejjednodušší to je asi metodou setCatalog. Můžeš ho nastavovat třeba v beforeRender.

Editoval voda (9. 1. 2012 10:24)

R@100
Člen | 2
+
0
-

vdaka voda, este otazka, sako sa sprava cache (mozno by som sa mal pytat na to inde), potrebujem nastavit, aby tie subory extra chacheoval a potom k nim nejak pristupoval?

voda
Člen | 561
+
0
-

cache řeš až bude aplikace pomalá, já to zatím nepotřeboval.

repli2dev
Člen | 57
+
0
-

voda napsal(a):

cache řeš až bude aplikace pomalá, já to zatím nepotřeboval.

No, experimentoval jsem trochu s keší (jen se čistě zajímám jestli to vůbec půjde) a zatím to vypadá, že ne.
Problém je očividně ve FileReaderu, který si při vytvoření ukládá file handle do _fp… Takže při uložení do keše a načtení z keše se objeví problém se seekto, protože dostane jako file handle 0, tzn. soubor není v instanci po načtení z keše otevřen.

Petrik.a.dost
Člen | 72
+
0
-

PHP 5.3.24 nette 2.1

Dobrý den,

chci se jen zepatat jakou verzi mám nainstalovat protože když do composeru zadám „composer require voda/php-translator“ tak to pak po mě chci verzi a nevím jakou tam mám dát… konkrétně to píše „Please provide a version constraint for the voda/php-translator requirement:“ … už nevím jak to mám nainstalovat ??

Předem moc děkuji za odpoved…:)

voda
Člen | 561
+
0
-

Když se podíváš na balíček na packagist.org, tak tam je uveden seznam verzí. V současnosti tam je jen verze 0.1.0. Doporučuji tedy buď 0.x.x nebo 0.1.x.

Více o verzích v dokumentaci composeru a na semver.org.

Petrik.a.dost
Člen | 72
+
0
-

Zdravím,

moc děkuji za radu composer nainstalovat php-translator. Jen mám ještě problém s knihovnou php-gettext, když do composer.json vložim kód, co je v návodu a aktualizuji composer, tak cmd vypíše:

[Seld\JsonLint\ParsingException]
„./composer.json“ does not contain valid JSON
Parse error on line 26:
…tester": „@dev" } "repositories“: [
---------------------^
Expected one of: ‚EOF‘, ‚}‘, ‚,‘, ‚]‘

update [–prefer-source] [–prefer-dist] [–dry-run] [–dev] [–no-dev] [–lock]
[–no-plugins] [–no-custom-installers] [–no-scripts] [–no-progress] [-v|vv|v
vv|--verbose] -o [packages1] … [packagesN]

přesně na řádce, kde začíná kód pro knihovnu php-gettext háže chybu že není validní composer.json a všude používám jen tabuátor jako v konfigu aby s tim nebyl problém když se kombinují mezery a tabulátory…
můj composer.json je:

{
„name“: „nette/sandbox“,
„description“: „The sandbox is a pre-packaged Nette Framework project, basic configured structure for your application.“,
„homepage“: „https://nette.org“,
„type“: „project“,
„license“: [„BSD-3-Clause“, „GPL-2.0“, „GPL-3.0“],
„authors“: [
{
„name“: „David Grudl“,
„homepage“: „http://davidgrudl.com“
},
{
„name“: „Nette Community“,
„homepage“: „https://nette.org/en/contributors?lang=en“
}
],
„require“: {
„php“: „>= 5.3.0“,
„nette/nette“: „@dev",
"dg/adminer-custom“: „1“,
„texy/texy“: „v2.3“,
„voda/php-translator“: „0.1“
},
„require-dev“: {
„nette/tester“: „@dev"
}
"repositories“: [
{
„type“: „package“,
„package“: {
„name“: „php-gettext/php-gettext“,
„version“: „1.0.11“,
„dist“: {
„type“: „tar“,
„url“: „https://launchpad.net/php-gettext/trunk/1.0.11/+download/php-gettext-1.0.11.tar.gz“
},
„autoload“: {
„classmap“: [
„gettext.php“,
„streams.php“
]
}
}
}
],
„require“: {
„php-gettext/php-gettext“ : „1.0.*“
}
}

a laděnka vyzuje:

Nette\Utils\NeonException

Unexpected indentation. on line 30, column 4 na místo v config.neon konkretně na arguments na třicáte řádce, ale to může být tím že nemám tu knihovnu php-gettext.

translator:
29: class: Antee\i18n\GettextTranslator
30: arguments:
31: – „%appDir%/locale/cs.mo“

Předem moc děkuji za odpověď.

Petr

voda
Člen | 561
+
0
-

Chybí ti čárka za require-dev sekcí

„require-dev“: {
 „nette/tester“: „@dev“
 } <--- tady ti chybí čárka
 „repositories“: [

Editoval voda (30. 10. 2013 21:27)

Petrik.a.dost
Člen | 72
+
0
-

zdravím PHP 5.3.24 nette 2.1

laděnka vyzuje nevítě někdo čím by to mohlo být:

Nette\Utils\NeonException

Unexpected indentation. on line 30, column 4 na místo v config.neon konkretně na arguments na třicáte řádce, ale to může být tím že nemám tu knihovnu php-gettext.

translator:
29: class: Antee\i18n\GettextTranslator
30: arguments:
31: – „%appDir%/locale/cs.mo“

Předem moc děkuji za odpověď.

Petr

voda
Člen | 561
+
0
-

Stačí si přeložit text výjimky:

Unexpected indentation. on line 30, column 4

Máš tam špatné odsazení, asi ti na řádku 30 chybí jeden tabulátor.

Petrik.a.dost
Člen | 72
+
0
-

díky už to mám opravené, ale ještě mám jeden takový problém a to Found sections ‚translator‘, ‚arguments‘ in configuration, but corresponding extensions are missing na řádku 25

16: // Enable RobotLoader – this will load all classes automatically
17: $configurator->createRobotLoader()
18: ->addDirectory(__DIR__)
19: ->addDirectory(__DIR__ . ‚/../vendor/others‘)
20: ->register();
21:
22: // Create Dependency Injection container from config.neon file
23: $configurator->addConfig(__DIR__ . ‚/config/config.neon‘);
24: $configurator->addConfig(__DIR__ . ‚/config/config.local.neon‘);
25: $container = $configurator->createContainer();
26:
27: return $container;

Editoval Petrik.a.dost (31. 10. 2013 20:46)

Petrik.a.dost
Člen | 72
+
0
-

zkoušel jsem si pohrat s těma tabulatorama a ted to hlásí Class Antee\i18n\GettextTranslator used in service ‚translator‘ has not been found or is not instantiable zase na řádce 25

voda
Člen | 561
+
0
-

Smazat cache nepomůže? Jiné knihovny instalované přes composer ti fungují? Máš načtený autoloader.php z vendor složky?

Petrik.a.dost
Člen | 72
+
0
-

jiné knihovny přes composer jsem nezkoušel, jinak promazat cache nepomohlo a autoloader načítám v composeru
„autoload“: {
„files“: [ „Nette/loader.php“ ]
}

jestli je to správně?

voda
Člen | 561
+
0
-

V bootstrap.php bys měl mít řádek require __DIR__ . '/../vendor/autoload.php';, máš ho tam?
Viz sandbox

Petrik.a.dost
Člen | 72
+
0
-

jojo tohle tam všechno mám :

// Load Nette Framework or autoloader generated by Composer
require __DIR__ . ‚/../vendor/autoload.php‘;

$configurator = new Nette\Configurator;

// Enable Nette Debugger for error visualisation & logging
//$configurator->setDebugMode(TRUE);
$configurator->enableDebugger(__DIR__ . ‚/../log‘);

// Specify folder for cache
$configurator->setTempDirectory(__DIR__ . ‚/../temp‘);

// Enable RobotLoader – this will load all classes automatically
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->addDirectory(__DIR__ . ‚/../vendor/others‘)
->register();

// Create Dependency Injection container from config.neon file
$configurator->addConfig(__DIR__ . ‚/config/config.neon‘);
$configurator->addConfig(__DIR__ . ‚/config/config.local.neon‘);
$container = $configurator->createContainer();

return $container;

Petrik.a.dost
Člen | 72
+
0
-

jesli taky nemám chybu v config.neon :

#
# SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser!
#
# If you don't protect this directory from direct web access, anybody will be able to see your passwords.
# https://nette.org/en/security-warning

#
parameters:

php:
	date.timezone: Europe/Prague
	# zlib.output_compression: yes

nette:
	application:
		errorPresenter: Error
		mapping:
			*: App\*Module\*Presenter

	session:
		expiration: 14 days


services:
	- Model\PasUser
	- Model\UserManager
	- App\RouterFactory
	router: @App\RouterFactory::createRouter
	translator:
		class: Antee\i18n\GettextTranslator
		arguments:
			- "%appDir%/locale/cs.mo"

Editoval Petrik.a.dost (31. 10. 2013 21:29)

Petrik.a.dost
Člen | 72
+
0
-

když to v config.neon změním na :

#
# SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser!
#
# If you don't protect this directory from direct web access, anybody will be able to see your passwords.
# https://nette.org/en/security-warning
#
parameters:

php:
	date.timezone: Europe/Prague
	# zlib.output_compression: yes

nette:
	application:
		errorPresenter: Error
		mapping:
			*: App\*Module\*Presenter

	session:
		expiration: 14 days


	translator:
		class: Antee\i18n\GettextTranslator
		arguments:
			- "%appDir%/locale/cs.mo"

services:
	- Model\PasUser
	- Model\UserManager
	- App\RouterFactory
	router: @App\RouterFactory::createRouter

tak už to chybu nehlásí, ale když zkusím v templatu něco vložit fo {_"nějakýText"} tak to hodí chybu

Call to undefined method Nette\Templating\FileTemplate::translate()

na této řádce

<legend><?php echo Nette\Templating\Helpers::escapeHtml($template->translate(„Přehled uživatelů“), ENT_NOQUOTES) ?></legend>

voda
Člen | 561
+
0
-

To první bylo správně sekce translator, patří pod sekci services. Nahraj někam celý projekt, takhle asi nic nevyřešíme.