Detect, When Language-Specific Document Or View Is Not Available

Yii has a great, powerful, yet easy to implement, internationalization system, which (in current implementation) is always serving default-language document or view, if language-specific document (for currently selected language) is not available.

This is great, but I would like to enhance this mechanism with a clear message displayed to the user in such situation. Something like: “Document, you’ve requested isn’t available in your language yet. Please, use original one instead”.

But I have a quite big problem in detecting such situations. Simple comparing, for example:


$filename = 'files/pages/'.$page.'.txt';

$localizedFilename = Yii::app()->findLocalizedFile($filename);

fails, because these two variables will be equal in both situations – i.e. when users request document in non-default language, that does not exists (default language document is served then) and, when requesting document in default language.

Does anyone have any idea, how to implement this. What code should I write to have 100% sure method for catching situation, when user requests a document, that is not available in his language.

What about this:




$filename = 'files/pages/'.$page.'.txt';


if(Yii::app()->language !== Yii::app()->sourceLanguage)

{

  $localizedFilename = Yii::app()->findLocalizedFile($filename);

  if($localizedFilename === $filename)

    throw new CHttpException(404, 'This document is not available in your language');

  

  $filename = $localizedFilename;

}



Dear Friend.

I think here we can rise the event ‘onMissingTranslation’ of messege component.

Declare the component in main.php




.....................................................................................

'messages'=>array(

			'class'=>'CPhpMessageSource',

			'behaviors'=>array(

				'class'=>'messageBehavior',

			),

		

		),

......................................................................................



protected/components/messageBehavior.php




<?php

class messageBehavior extends CBehavior

{   

	public function events()

	{	return array(

			'onMissingTranslation'=>'messageOnMissing',

		);

	}

	

	public function messageOnMissing($event)

	{   

                $owner=$this->owner;

	        /**

                 *Following are available.

                 *$event->message.

                 *$event->category.

                 *$event->language.

                 *You can customize the message here.

                  */

		Yii::app()->params['missingTranslation']="file not found";

	}

}

?>




Now in a view, after failed translation, we can call like this.




echo Yii::app()->params['missingTranslation'];



Regards.

[size="2"]Tsunami, your solution works just great! I modified it to my needs (using [/size]setFlash[size="2"]), because I wanted to display additional message and original text instead of throwing exception. But your base concept remains! Thank you…[/size]

Next big question, is how to adapt this solution also to views? To add some extra message in the beginning of view contents (i.e. inside layout) [size="2"]rendered in default, base language, if selected external language view does not exists?[/size]

[size="2"]This seems to be a harder task, as Yii handles searching for translated versions of a views internally. My first attempt was to use own class, extending CViewRenderer or overload render() function in my own base Controller class, which is base to all my controllers.[/size]

[size="2"]But since I want to display such messages only for part of controllers (i.e. frontend one), I think this is a wrong path. And I think I have to take a look around behaviors.[/size]

[size=“2”]But I’ll be more than happy to look at any other option, if you or someone else already have such solution (or idea).[/size]