I added one library for gettext translation. Added corresponding po and mo files.
And the translation is working fine.
Now when I update my po file, change some translation.. after that when I reload the page, I am getting the old translation, not the new.
Here is the Library code:
/**
* This method overides the original load method. Its duty is loading the domain files by config or by default internal settings.
*
*/
function load_gettext($userlang = false) {
/* I want the super object */
if ($userlang)
$this->gettext_language = $userlang;
else
$this->gettext_language = 'it_IT';
log_message('debug', 'Gettext Class gettext_language was set by parameter:' . $this->gettext_language);
putenv("LANG=$this->gettext_language");
setlocale(LC_ALL, $this->gettext_language);
/* Let's set the path of .po files */
$this->gettext_path = APPPATH . 'language/locale';
log_message('debug', 'Gettext Class path chosen is: ' . $this->gettext_path);
bindtextdomain($this->gettext_domain, $this->gettext_path);
textdomain($this->gettext_domain);
log_message('debug', 'Gettext Class the domain chosen is: ' . $this->gettext_domain);
return true;
}
/**
* Plural forms added by Tchinkatchuk
* http://www.codeigniter.com/forums/viewthread/2168/
*/
/**
* The translator method
*
* #param string $original the original string to translate
* #param array $aParams the plural parameters
* #return the string translated
*/
function _trans($original, $aParams = false) {
if (isset($aParams['plural']) && isset($aParams['count'])) {
$sTranslate = ngettext($original, $aParams['plural'], $aParams['count']);
$sTranslate = $this->replaceDynamically($sTranslate, $aParams);
} else {
$sTranslate = gettext($original);
if (is_array($aParams) && count($aParams))
$sTranslate = $this->replaceDynamically($sTranslate, $aParams);
}
return $sTranslate;
}
This is the usage in a controller:
$this->pos_language->load_gettext('fr_FR');
echo $this->pos_language->_trans('Hello world, good morning');
I think you need to compile your .po files to .mo files. Gettext uses the .mo file, the .po is just a human readable form.
If you haven't done the compilation step, your application is still reading your old .mo files, with the untranslated strings...
This page has some more info about gettext translation: http://wiki.creativecommons.org/Translating_PO_Files
I wrote a helper to integrate php-gettext with Smarty & Code Igniter 2
http://bit.ly/rrITVx
I hope it might help
Related
I've got micro-kernel Symfony project with custom catalog structure.
I used this: https://github.com/ikoene/symfony-micro
How can I override e.g. Twig Resources (Exception views)?
Cookbook says that I should create a directory called TwigBundle in my Resources directory.
I made \AppBundle\Resources\TwigBundle\views\Exception directory. Overriding view does not seem to work.
Thanks for using the microkernel setup. Here's how to override exception views.
1. Create a custom ExceptionController
First off, we're gonna create our own ExceptionController which extends the base ExceptionController. This will allow us to overwrite the template path.
<?php
namespace AppBundle\Controller\Exception;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController as BaseExceptionController;
use Symfony\Component\HttpFoundation\Request;
class ExceptionController extends BaseExceptionController
{
/**
* #param Request $request
* #param string $format
* #param int $code
* #param bool $showException
*
* #return string
*/
protected function findTemplate(Request $request, $format, $code, $showException)
{
$name = $showException ? 'exception' : 'error';
if ($showException && 'html' == $format) {
$name = 'exception_full';
}
// For error pages, try to find a template for the specific HTTP status code and format
if (!$showException) {
$template = sprintf('AppBundle:Exception:%s%s.%s.twig', $name, $code, $format);
if ($this->templateExists($template)) {
return $template;
}
}
// try to find a template for the given format
$template = sprintf('#Twig/Exception/%s.%s.twig', $name, $format);
if ($this->templateExists($template)) {
return $template;
}
// default to a generic HTML exception
$request->setRequestFormat('html');
return sprintf('#Twig/Exception/%s.html.twig', $showException ? 'exception_full' : $name);
}
}
2. Create the error templates
Create templates for the different error codes:
error.html.twig
error403.html.twig
error404.html.twig
In this example, the exception templates would be placed in AppBundle/Resources/views/Exception/
3. Override the default ExceptionController
Now let's point to our new exception controller in the configuration.
twig:
exception_controller: app.exception_controller:showAction
I really like your solution, but I found another way how to do it without custom exception controller.
I realized that automatical additional check for overrided templates happens in directory Resources in the directory when you store your kernel class.
So, for structure in your repo it's:
/Resources/TwigBundle/views/Exception/
Finally I changed a little bit the directory structure to have a 'app' directory with kernel file inside. Just like in the default Symfony project.
I want to put my module in Prestashop market place, and make it standard everyone can use it. This plugin needs to know the admin directory name dynamically to do its service.
I have searched on the Internet a lot of times, but I didn't find a solution to this issue.
You can use _PS_ADMIN_DIR_ witch is set in [your_admin_dir]/index.php:
if (!defined('_PS_ADMIN_DIR_')) {
define('_PS_ADMIN_DIR_', getcwd());
}
This constant is only set when you're on an admin context. Your FrontOffice doesn't have knowledge of this directory and should not for obvious security reason.
There's also a getAdminLink method in class Link:
/**
* Use controller name to create a link
*
* #param string $controller
* #param bool $with_token include or not the token in the url
* #return string url
*/
public function getAdminLink($controller, $with_token = true)
{
$id_lang = Context::getContext()->language->id;
$params = $with_token ? array('token' => Tools::getAdminTokenLite($controller)) : array();
return Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false);
}
Example:
// Here we create a link to the dashboard without token
$this->context->link->getAdminLink(Tab::getClassNameById(1), false)
How can I compile a blade template from a string rather than a view file, like the code below:
<?php
$string = '<h2>{{ $name }}</h2>';
echo Blade::compile($string, array('name' => 'John Doe'));
?>
http://paste.laravel.com/ujL
I found the solution by extending BladeCompiler.
<?php namespace Laravel\Enhanced;
use Illuminate\View\Compilers\BladeCompiler as LaravelBladeCompiler;
class BladeCompiler extends LaravelBladeCompiler {
/**
* Compile blade template with passing arguments.
*
* #param string $value HTML-code including blade
* #param array $args Array of values used in blade
* #return string
*/
public function compileWiths($value, array $args = array())
{
$generated = parent::compileString($value);
ob_start() and extract($args, EXTR_SKIP);
// We'll include the view contents for parsing within a catcher
// so we can avoid any WSOD errors. If an exception occurs we
// will throw it out to the exception handler.
try
{
eval('?>'.$generated);
}
// If we caught an exception, we'll silently flush the output
// buffer so that no partially rendered views get thrown out
// to the client and confuse the user with junk.
catch (\Exception $e)
{
ob_get_clean(); throw $e;
}
$content = ob_get_clean();
return $content;
}
}
Small modification to the above script.
You can use this function inside any class without extending the BladeCompiler class.
public function bladeCompile($value, array $args = array())
{
$generated = \Blade::compileString($value);
ob_start() and extract($args, EXTR_SKIP);
// We'll include the view contents for parsing within a catcher
// so we can avoid any WSOD errors. If an exception occurs we
// will throw it out to the exception handler.
try
{
eval('?>'.$generated);
}
// If we caught an exception, we'll silently flush the output
// buffer so that no partially rendered views get thrown out
// to the client and confuse the user with junk.
catch (\Exception $e)
{
ob_get_clean(); throw $e;
}
$content = ob_get_clean();
return $content;
}
For anyone still interested in this, they've added it to Laravel 9
use Illuminate\Support\Facades\Blade;
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);
https://laravel.com/docs/9.x/blade#rendering-inline-blade-templates
I just stumbled upon the same requirement! For me, i had to fetch a blade template stored in DB & render it to send email notifications.
I did this in laravel 5.8 by kind-of Extending \Illuminate\View\View. So, basically i created the below class & named him StringBlade (I couldn't find a better name atm :/)
<?php
namespace App\Central\Libraries\Blade;
use Illuminate\Filesystem\Filesystem;
class StringBlade implements StringBladeContract
{
/**
* #var Filesystem
*/
protected $file;
/**
* #var \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
protected $viewer;
/**
* StringBlade constructor.
*
* #param Filesystem $file
*/
public function __construct(Filesystem $file)
{
$this->file = $file;
$this->viewer = view();
}
/**
* Get Blade File path.
*
* #param $bladeString
* #return bool|string
*/
protected function getBlade($bladeString)
{
$bladePath = $this->generateBladePath();
$content = \Blade::compileString($bladeString);
return $this->file->put($bladePath, $content)
? $bladePath
: false;
}
/**
* Get the rendered HTML.
*
* #param $bladeString
* #param array $data
* #return bool|string
*/
public function render($bladeString, $data = [])
{
// Put the php version of blade String to *.php temp file & returns the temp file path
$bladePath = $this->getBlade($bladeString);
if (!$bladePath) {
return false;
}
// Render the php temp file & return the HTML content
$content = $this->viewer->file($bladePath, $data)->render();
// Delete the php temp file.
$this->file->delete($bladePath);
return $content;
}
/**
* Generate a blade file path.
*
* #return string
*/
protected function generateBladePath()
{
$cachePath = rtrim(config('cache.stores.file.path'), '/');
$tempFileName = sha1('string-blade' . microtime());
$directory = "{$cachePath}/string-blades";
if (!is_dir($directory)) {
mkdir($directory, 0777);
}
return "{$directory}/{$tempFileName}.php";
}
}
As you can already see from the above, below are the steps followed:
First converted the blade string to the php equivalent using \Blade::compileString($bladeString).
Now we have to store it to a physical file. For this storage, the frameworks cache directory is used - storage/framework/cache/data/string-blades/
Now we can ask \Illuminate\View\Factory native method 'file()' to compile & render this file.
Delete the temp file immediately (In my case i didn't need to keep the php equivalent file, Probably same for you too)
And Finally i created a facade in a composer auto-loaded file for easy usage like below:
<?php
if (! function_exists('string_blade')) {
/**
* Get StringBlade Instance or returns the HTML after rendering the blade string with the given data.
*
* #param string $html
* #param array $data
* #return StringBladeContract|bool|string
*/
function string_blade(string $html, $data = [])
{
return !empty($html)
? app(StringBladeContract::class)->render($html, $data)
: app(StringBladeContract::class);
}
}
Now i can call it from anywhere like below:
<?php
$html = string_blade('<span>My Name is {{ $name }}</span>', ['name' => 'Nikhil']);
// Outputs HTML
// <span>My Name is Nikhil</span>
Hope this helps someone or at-least maybe inspires someone to re-write in a better way.
Cheers!
I'm not using blade this way but I thought that the compile method accepts only a view as argument.
Maybe you're looking for:
Blade::compileString()
It's a old question. But I found a package which makes the job easier.
Laravel Blade String Compiler renders the blade templates from the string value. Check the documentation on how to install the package.
Here is an example:
$template = '<h1>{{ $name }}</h1>'; // string blade template
return view (['template' => $template], ['name' => 'John Doe']);
Note: The package is now updated to support till Laravel 6.
I know its pretty old thread, but today also requirement is same.
Following is the way I solved this on my Laravel 5.7 (but this will work with any laravel version greater than version 5), I used the knowledge gained from this thread and few other threads to get this working (will leave links to all threads at the end, if this help up-vote those too)
I added this to my helper.php (I used this technique to add helper to my project, but you can use this function directly as well)
if (! function_exists('inline_view')) {
/**
* Get the evaluated view contents for the given blade string.
*
* #param string $view
* #param array $data
* #param array $mergeData
* #return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
function inline_view($view = null, $data = [], $mergeData = [])
{
/* Create a file with name as hash of the passed string */
$filename = hash('sha1', $view);
/* Putting it in storage/framework/views so that these files get cleared on `php artisan view:clear*/
$file_location = storage_path('framework/views/');
$filepath = storage_path('framework/views/'.$filename.'.blade.php');
/* Create file only if it doesn't exist */
if (!file_exists($filepath)) {
file_put_contents($filepath, $view);
}
/* Add storage/framework/views as a location from where view files can be picked, used in make function below */
view()->addLocation($file_location);
/* call the usual view helper to render the blade file created above */
return view($filename, $data, $mergeData);
}
}
Usage is exactly same as laravel's view() helper, only that now first parameter is the blade string
$view_string = '#if(strlen($name_html)>6)
<strong>{{ $name_html }}</strong>
#else
{{$name_html}}
#endif';
return inline_view($view_string)->with('name_html', $user->name);
return inline_view($view_string, ['name_html' => $user->name]);
References:
https://stackoverflow.com/a/31435824/4249775
https://stackoverflow.com/a/33594452/4249775
Laravel 9 :
use Illuminate\Support\Facades\Blade;
return Blade::render('Your Blade Content {{ $parameter1}}', ['parameter1' => 'Name']);
I would like to use YUI compressor with minify PHP rather than the default JSmin. Does anyone have experience setting this up?
Right now I am using the groupsConfig.php to combine the JS.
return array(
'jsAll' => array('//contenido/themes/bam/assets/js/jquery.js', '//contenido/themes/bam/assets/js/modernizr.js','//contenido/themes/bam/assets/js/imgpreload.js', '//contenido/themes/bam/assets/js/imgpreload.js', '//contenido/themes/bam/assets/js/history.js','//contenido/themes/bam/assets/js/ajaxify.js', '//contenido/themes/bam/assets/js/isotope.js'),
'jsHome' => array('//contenido/themes/bam/assets/js/easing.js','//contenido/themes/bam/assets/js/scrollable.js', '//contenido/themes/bam/assets/js/home.js'),
'cssAll' => array('//contenido/themes/bam/bam.css'),
);
As it says on the homepage:
Uses an enhanced port of Douglas Crockford's JSMin library and custom classes to minify CSS and HTML
I have the following code in config.php, but I get a 500 error when trying to view the combined js file:
function yuiJs($js) {
require_once '/lib/Minify/YUICompressor.php';
Minify_YUICompressor::$jarFile = '/lib/yuicompressor-2.4.2.jar';
Minify_YUICompressor::$tempDir = '/temp';
return Minify_YUICompressor::minifyJs($js);
}
$min_serveOptions['minifiers']['application/x-javascript'] = 'yuiJs';
It also appears that there are several lines in lib/Minify/YUICompressor.php that need to be configured, and I'm not sure if I'm doing it right:
class Minify_YUICompressor {
/**
* Filepath of the YUI Compressor jar file. This must be set before
* calling minifyJs() or minifyCss().
*
* #var string
*/
public static $jarFile = '../yuicompressor-2.4.2.jar';
/**
* Writable temp directory. This must be set before calling minifyJs()
* or minifyCss().
*
* #var string
*/
public static $tempDir = '../../temp/';
/**
* Filepath of "java" executable (may be needed if not in shell's PATH)
*
* #var string
*/
public static $javaExecutable = 'java';
I had the same problem on windows. It seems jar file needs to be executable in order to run yui compressor. So, i have to remove excutable check from YUICompressor.php
#132
private static function _prepare()
{
if (! is_file(self::$jarFile)) {
throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not a valid file.');
}
// if (! is_executable(self::$jarFile)) {
// throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not executable.');
// }
if (! is_dir(self::$tempDir)) {
throw new Exception('Minify_YUICompressor : $tempDir('.self::$tempDir.') is not a valid direcotry.');
}
if (! is_writable(self::$tempDir)) {
throw new Exception('Minify_YUICompressor : $tempDir('.self::$tempDir.') is not writable.');
}
}
and that works fine.
I just moved my website to another server and i got this error message using smarty template
http://bit.ly/5MZu2A
Here is part of the smarty file:
/**
* DIR_SEP isn't used anymore, but third party apps might
*/
if(!defined('DIR_SEP')) {
define('DIR_SEP', DIRECTORY_SEPARATOR);
}
/**
* set SMARTY_DIR to absolute path to Smarty library files.
* if not defined, include_path will be used. Sets SMARTY_DIR only if user
* application has not already defined it.
*/
if (!defined('SMARTY_DIR')) {
define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
}
if (!defined('SMARTY_CORE_DIR')) {
define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
}
define('SMARTY_PHP_PASSTHRU', 0);
define('SMARTY_PHP_QUOTE', 1);
define('SMARTY_PHP_REMOVE', 2);
define('SMARTY_PHP_ALLOW', 3);
/**
* #package Smarty
*/
class Smarty
{
/**##+
* Smarty Configuration Section
*/
/**
* The name of the directory where templates are located.
*
* #var string
*/
var $template_dir = 'templates';
/**
* The directory where compiled templates are located.
*
* #var string
*/
var $compile_dir = 'templates_c';
/**
* The directory where config files are located.
*
* #var string
*/
var $config_dir = 'configs';
/**
* An array of directories searched for plugins.
*
* #var array
*/
var $plugins_dir = array('plugins');
And here is the path of my website and smarty file respectively
/home/cd/public_html
/home/cd/public_html/smarty/Smarty.class.php
You should post the PHP code where you sey up the smarty object - where you should declare paths if different from default.
This works fine for me:
$smarty = new Smarty;
$smarty->template_dir = "./templates" ;
$smarty->compile_dir = "./templates_c" ;
$smarty->cache_dir = "./cache" ;
$smarty->config_dir = "./includes";
where the path to said folders is relative to the calling script, even if you keep it in an included file.
Absolute paths should be error-proof, I guess:
require '/home/cd/public_html/smarty/Smarty.class.php';
$smarty = new Smarty;
$smarty->template_dir = "/home/cd/public_html/themes/default/templates" ;
$smarty->compile_dir = "/home/cd/public_html/themes/default/templates_c" ;
$smarty->cache_dir = "/home/cd/public_html/themes/default/cache" ;
$smarty->config_dir = "/home/cd/public_html/themes/default/includes";
as long as you have a cache and an include folder there (you may change their names freely, or put them elsewhere). Add this while working out the hitches:
$smarty->debugging = true;
to send a complete listing of smarty variables to a pop-up page (you might have to allow this in your browser's pop-up blocker).
You don't have to change Smarty.class.php at all. You probably have a declaration like $smarty = new Smarty() in your index.php where you should find the $smarty->template_dir = "path_to_your_dir";.
I fixed it, at least my hosting company did
The problem was from the database, smarty was using the previous path from the other hosting company i moved from so i needed to update the path.
Thanks!