Skip to content

Commit

Permalink
Web Interface was added and some minor changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
hpolthof committed Jun 11, 2015
1 parent 31dfc90 commit b77fb0e
Show file tree
Hide file tree
Showing 13 changed files with 403 additions and 6 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "0.1.x-dev"
"dev-master": "0.2.x-dev"
}
}
}
19 changes: 19 additions & 0 deletions config/translation-db.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
<?php

return [
/**
* To save some time interacting with the database, you can turn
* the storing of the viewed_at field off.
*/
'update_viewed_at' => true,

/**
* This is the prefix for on which URI the Translations Manager will
* be available. You can leave it just as is in most cases.
*/
'route_prefix' => '_translations',

/**
* If your using the Laravel Debugbar provided by Barryvdh\Debugbar
* you might want to disable this in the Translations Manager.
* This interface can generate a bunch of Ajax calls that will slow
* the translation process down.
* You can however turn it on, the choice is yours.
*/
'disable_debugbar' => true,
];
24 changes: 23 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,26 @@ php artisan migrate
And that's all there is to it!

## Web interface
Although it's currently unavailable, a web interface to ease your translations once more, is scheduled to be added soon.
To prevent you from having to access the database for every translation, a web interface is available to manager your
translations.

Direct your browser to:
```
http://{projectUrl}/_translations
```
> This location can also be changed in the ```translation-db.php``` config file.
### Configure your workset
At the Translations Manager you'll have to select a certain group, as well as a locale. The first locale you'll select
represents the language you'll be using as a reference to create your translations.
In the textfield you should enter the locale you want to create or edit.
> The locale you should enter in the textfield, can be any locale. There is no need to predefine anything. The entries will be created just as you submit your translations.
After selecting these settings, just hit the Load button and all the collected translations will be listed.

### Editing
After your translation keys are loaded, a textbox will appear on each row. You can just type in your translation, when
the textbox loses it's focus, the translation will be saved.
> The saving takes place through some Ajax calls. If you are using the [Laravel Debugbar](https://github.com/barryvdh/laravel-debugbar)
> it will be advised to disable the Debugbar as every Ajax request slows your browser down. By default de Debugbar will
> therefor be disabled, it the Debugbar is used. If you want to leave the Debugbar on, you can just enable it within
> the ```translation-db.php``` config file.
7 changes: 7 additions & 0 deletions resources/lang/en/manager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php
return [
'title' => 'Translations Manager',
'help' => 'Select your preferred group and locale below and start translating.',
'locale_placeholder' => 'Enter the locale you wish to edit. (example: en)',
'button' => 'Load',
];
7 changes: 7 additions & 0 deletions resources/lang/nl/manager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php
return [
'title' => 'Vertalingen beheer',
'help' => 'Selecteer de groep en de taal van uw voorkeur en start met vertalen.',
'locale_placeholder' => 'Geef de taal op die uw wilt bewerken. (bijvoorbeeld: nl)',
'button' => 'Inladen',
];
93 changes: 93 additions & 0 deletions src/Controllers/TranslationsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php namespace Hpolthof\Translation\Controllers;

use Hpolthof\Translation\TranslationException;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class TranslationsController extends Controller {

public function __construct() {
// Disable the Laravel Debugbar
$app = app();
if($app->offsetExists('debugbar') && $app['config']->get('translation-db.disable_debugbar')) {
$app['debugbar']->disable();
}
}

public function getIndex() {
return view('translation::index');
}

public function getGroups() {
return \DB::table('translations')
->select('group')
->distinct()
->orderBy('group')
->lists('group');
}

public function getLocales() {
return \DB::table('translations')
->select('locale')
->distinct()
->orderBy('locale')
->lists('locale');
}

public function postItems(Request $request) {
if(strlen($request->get('translate')) == 0) throw new TranslationException();

$base = \DB::table('translations')
->select('name', 'value')
->where('locale', $request->get('locale'))
->where('group', $request->get('group'))
->orderBy('name')
->get();
$new = \DB::table('translations')
->select('name', 'value')
->where('locale', strtolower($request->get('translate')))
->where('group', $request->get('group'))
->orderBy('name')
->lists('value', 'name');

foreach($base as &$item) {
$translate = null;

if(array_key_exists($item->name, $new)) {
$translate = $new[$item->name];
}
$item->translation = $translate;
}

return $base;
}

public function postStore(Request $request) {
$item = \DB::table('translations')
->where('locale', strtolower($request->get('locale')))
->where('group', $request->get('group'))
->where('name', $request->get('name'))->first();

$data = [
'locale' => strtolower($request->get('locale')),
'group' => $request->get('group'),
'name' => $request->get('name'),
'value' => $request->get('value'),
'updated_at' => date_create(),
];

if($item === null) {
$data = array_merge($data, [
'created_at' => date_create(),
]);
$result = \DB::table('translations')->insert($data);
} else {
$result = \DB::table('translations')->where('id', $item->id)->update($data);
}

if(!$result) {
throw new TranslationException('Database error...');
}
return 'OK';
}
}
57 changes: 57 additions & 0 deletions src/DataCollector/TranslationCollector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php namespace Hpolthof\Translation\DataCollector;

use DebugBar\DataCollector\DataCollector;
use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter;

class TranslationCollector extends DataCollector
{
protected $items = array();
protected $collect_data;
/**
* Create a ViewCollector
*
* @param bool $collectData Collects view data when tru
*/
public function __construct($collectData = true)
{
$this->collect_data = $collectData;
$this->name = 'translation';
$this->items = array();
$this->exporter = new ValueExporter();
}

public function getName()
{
return 'translation';
}

public function getWidgets()
{
return array(
'views' => array(
'icon' => 'leaf',
'widget' => 'PhpDebugBar.Widgets.TemplatesWidget',
'map' => 'translation',
'default' => '[]'
),
'views:badge' => array(
'map' => 'translation.count',
'default' => 0
)
);
}

public function addTranslation($translation)
{
$this->items[] = $translation;
}

public function collect()
{
$items = $this->items;
return array(
'count' => count($items),
'translation' => $items,
);
}
}
4 changes: 2 additions & 2 deletions src/DatabaseLoader.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?php namespace Hpolthof\Translation;

use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Translation\LoaderInterface;

class DatabaseLoader implements LoaderInterface {

protected $_app = null;

public function __construct($app)
public function __construct(Application $app)
{
$this->_app = $app;
}
Expand Down
39 changes: 38 additions & 1 deletion src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ public function register()
// configuration so we can easily get both of these values from there.
$locale = $app['config']['app.locale'];

$trans = new Translator($database, $loader, $locale);
$trans = new Translator($database, $loader, $locale, $app);

$trans->setFallback($app['config']['app.fallback_locale']);

return $trans;
});


}

public function boot()
Expand All @@ -50,6 +52,41 @@ public function boot()
$this->publishes([
__DIR__.'/../config/translation-db.php' => config_path('translation-db.php'),
]);

$this->loadViewsFrom(__DIR__.'/../views', 'translation');
$this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'translation');

// Only in debug mode the translations interface should be available.
if($this->app['config']->get('app.debug')) {
$routeConfig = [
'namespace' => 'Hpolthof\Translation\Controllers',
'prefix' => $this->app['config']->get('translation-db.route_prefix'),
];
$this->app['router']->group($routeConfig, function($router) {
$router->get('/', [
'uses' => 'TranslationsController@getIndex',
'as' => 'translations.index',
]);
$router->get('/groups', [
'uses' => 'TranslationsController@getGroups',
'as' => 'translations.groups',
]);
$router->get('/locales', [
'uses' => 'TranslationsController@getLocales',
'as' => 'translations.locales',
]);
$router->post('/items', [
'uses' => 'TranslationsController@postItems',
'as' => 'translations.items',
]);
$router->post('/store', [
'uses' => 'TranslationsController@postStore',
'as' => 'translations.store',
]);
});
}

$this->app['translation.database']->addNamespace(null, null);
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/Translator.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<?php namespace Hpolthof\Translation;;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Translation\LoaderInterface;
use Symfony\Component\Translation\TranslatorInterface;

class Translator extends \Illuminate\Translation\Translator implements TranslatorInterface {

public function __construct(LoaderInterface $database, LoaderInterface $loader, $locale)
protected $app = null;

public function __construct(LoaderInterface $database, LoaderInterface $loader, $locale, Application $app)
{
$this->database = $database;
$this->app = $app;
parent::__construct($loader, $locale);
}

Expand Down
67 changes: 67 additions & 0 deletions views/index.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>

@include('translation::javascript')
@include('translation::style')
</head>
<body>

<div class="container-fluid" ng-app="trans" ng-controller="Translations">

<h1>{{ trans('translation::manager.title') }}</h1>
<p>
{{ trans('translation::manager.help') }}
</p>

<div ng-if="message" class="alert alert-[[ message.type ]]" role="alert">
[[ message.text ]]
</div>

<div class="row" style="margin-bottom:10px">

<div class="col-md-3">
<select ng-model="currentGroup" ng-change="clear()" class="form-control">
<option ng-repeat="group in groups">[[ group ]]</option>
</select>
</div>

<div class="col-md-4">
<select ng-model="currentLocale" ng-change="clear()" class="form-control">
<option ng-repeat="locale in locales">[[ locale ]]</option>
</select>
</div>

<div class="col-md-4">
<input ng-change="clear()" class="form-control" maxlength="2" type="text" ng-model="currentEditable" placeholder="{{ trans('translation::manager.locale_placeholder') }}" />
</div>

<div class="col-md-1">
<button class="btn btn-primary form-control" ng-click="fetch()">
{{ trans('translation::manager.button') }}
</button>
</div>
</div>

<div class="row datarow" ng-repeat="item in items">
<div class="col-md-3 text">
[[ item.name ]]
</div>
<div class="col-md-4 text">
[[ item.value ]]
</div>
<div class="col-md-5">
<textarea class="form-control" ng-blur="store($index)" ng-model="item.translation" onfocus="jQuery(this).closest('.row').addClass('bg-success');" onblur="jQuery(this).closest('.row').removeClass('bg-success');"></textarea>
</div>
</div>
</div>

</body>
</html>
Loading

0 comments on commit b77fb0e

Please sign in to comment.