Ignore:
Timestamp:
Jun 23, 2013, 4:11:29 PM (11 years ago)
Author:
mistic100
Message:

allow multiple language files in a plugin

Location:
extensions/plugin_lang_analysis
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • extensions/plugin_lang_analysis/admin.php

    r23421 r23467  
    77
    88include_once(PLA_PATH . 'include/functions.inc.php');
    9 
     9include_once(PHPWG_ROOT_PATH . '/admin/include/plugins.class.php');
     10$plugins = new plugins();
    1011
    1112/* PLUGINS LIST */
    1213if (!isset($_GET['plugin_id']))
    1314{
    14   $query = '
    15 SELECT *
    16   FROM '.PLUGINS_TABLE.'
    17   ORDER BY LOWER(id)
    18 ;';
    19 
    20   $plugins = hash_from_query($query, 'id');
    21 
    2215  $template->assign(array(
    2316    'PLA_STEP' => 'select',
    24     'PLA_PLUGINS' => $plugins,
     17    'PLA_PLUGINS' => $plugins->fs_plugins,
    2518    'F_ACTION' => PLA_ADMIN,
    2619    ));
     
    3124{
    3225  $files = list_plugin_files($_GET['plugin_id']);
     26  $language_files = list_plugin_languages_files($_GET['plugin_id']);
     27 
     28  $default_lang_files = get_loaded_in_main($_GET['plugin_id']);
     29  if (empty($default_lang_files))
     30  {
     31    $default_lang_files = count($language_files)==1 ? array_keys($language_files) : (
     32                            array_key_exists('plugin.lang', $language_files) ? array('plugin.lang') : array()
     33                            );
     34  }
    3335 
    3436  if (file_exists(PLA_PATH.'_data/'.$_GET['plugin_id'].'.php'))
    3537  {
    36     list($filename, $saved_files) = @include(PLA_PATH.'_data/'.$_GET['plugin_id'].'.php');
     38    $saved_files = include(PLA_PATH.'_data/'.$_GET['plugin_id'].'.php');
    3739  }
    3840  else
    3941  {
    4042    $saved_files = array();
    41     $filename = 'plugin.lang.php';
    4243  }
    4344 
     
    4748    {
    4849      $file = $saved_files[$file];
     50      $file['lang_files'] = array_intersect($file['lang_files'], array_keys($language_files));
    4951    }
    5052    else
     
    5355        'path' => $file,
    5456        'is_admin' => strpos($file, '/admin') === 0,
     57        'lang_files' => $default_lang_files
    5558        );
    5659    }
     
    6063  $template->assign(array(
    6164    'PLA_STEP' => 'config',
    62     'PLA_PLUGIN' => $_GET['plugin_id'],
     65    'PLA_PLUGIN' => $plugins->fs_plugins[ $_GET['plugin_id'] ],
    6366    'PLA_FILES' => $files,
    64     'PLA_FILENAME' => $filename,
     67    'PLA_LANG_FILES' => $language_files,
    6568    'F_ACTION' => PLA_ADMIN.'&plugin_id='.$_GET['plugin_id'].'&analyze',
    6669    'U_BACK' => PLA_ADMIN,
     
    7275  if (isset($_POST['files']))
    7376  {
    74     $filename = $_POST['filename'];
    75    
    7677    $files = array();
    77     foreach ($_POST['files'] as $file => $is_admin)
     78    foreach ($_POST['files'] as $file => $data)
    7879    {
    7980      $files[$file] = array(
    8081        'path' => $file,
    81         'is_admin' => $is_admin=='true',
     82        'is_admin' => $data['is_admin']=='true',
     83        'lang_files' => array(),
    8284        );
     85      if (!empty($data['lang_files']))
     86      {
     87        $files[$file]['lang_files'] = array_keys(array_filter($data['lang_files'], create_function('$f', 'return $f=="true";')));
     88      }
    8389    }
    8490   
    8591    $content = "<?php\nreturn ";
    86     $content.= var_export(array($filename, $files), true);
     92    $content.= var_export($files, true);
    8793    $content.= ";\n?>";
    8894   
     
    9298  else
    9399  {
    94     list($filename, $files) = include(PLA_PATH.'_data/'.$_GET['plugin_id'].'.php');
    95   }
    96  
     100    $files = include(PLA_PATH.'_data/'.$_GET['plugin_id'].'.php');
     101  }
    97102 
    98103  $strings = array();
     
    106111    foreach ($file_strings as $string => $lines)
    107112    {
    108       if (empty($strings[ $string ]))
    109         $strings[ $string ]['is_admin'] = $file_data['is_admin'];
    110       else
    111         $strings[ $string ]['is_admin'] = $strings[ $string ]['is_admin'] && $file_data['is_admin'];
    112      
    113       $strings[ $string ]['files'][ $file ] = $lines;
     113      $strings[ $string ]['files'][ $file ] = $file_data + array('lines' => $lines);
    114114    }
    115115  }
     
    118118  $lang_common = load_language_file(PHPWG_ROOT_PATH.'language/en_UK/common.lang.php');
    119119  $lang_admin = load_language_file(PHPWG_ROOT_PATH.'language/en_UK/admin.lang.php');
    120   $lang_plugin = load_language_file(PHPWG_PLUGINS_PATH.$_GET['plugin_id'].'/language/en_UK/'.$filename);
     120 
     121  $language_files = list_plugin_languages_files($_GET['plugin_id']);
     122  foreach ($language_files as $name => $path)
     123  {
     124    $lang_plugin[ $name ] = load_language_file(PHPWG_PLUGINS_PATH.$_GET['plugin_id'].$path);
     125  }
    121126 
    122127  // analyze
    123128  foreach ($strings as $string => &$string_data)
    124129  {
     130    // find where teh string is defined
    125131    $string_data['in_common'] = array_key_exists($string, $lang_common);
    126132    $string_data['in_admin'] = array_key_exists($string, $lang_admin);
    127     $string_data['in_plugin'] = array_key_exists($string, $lang_plugin);
    128    
    129     if ($string_data['in_plugin'] && ($string_data['in_common'] || ($string_data['is_admin'] && $string_data['in_admin'])))
     133    $string_data['in_plugin'] = array();
     134    foreach ($language_files as $name => $path)
     135    {
     136      if (array_key_exists($string, $lang_plugin[$name])) $string_data['in_plugin'][] = $name;
     137    }
     138   
     139    $missing = $useless = $ok = false;
     140    $string_data['is_admin'] = true;
     141   
     142    // analyze for each file where the string exists
     143    foreach ($string_data['files'] as $file => &$file_data)
     144    {
     145      // the string is "admin" if all files are "admin"
     146      $string_data['is_admin'] &= $file_data['is_admin'];
     147     
     148      // find if the string is translated in one of the language files included in this file
     149      $exists = false;
     150      foreach ($file_data['lang_files'] as $lang_file)
     151      {
     152        if (in_array($lang_file, $string_data['in_plugin']))
     153        {
     154          $exists = true;
     155          break;
     156        }
     157      }
     158     
     159      // useless if translated in the plugin AND in common or admin
     160      if ($exists && ($string_data['in_common'] || ($file_data['is_admin'] && $string_data['in_admin'])))
     161      {
     162        $file_data['stat'] = 'useless';
     163        $useless = true;
     164      }
     165      // missing if not translated in the plugin NOR in common or admin
     166      else if (!$exists && !$string_data['in_common'] && (!$file_data['is_admin'] || !$string_data['in_admin']))
     167      {
     168        $file_data['stat'] = 'missing';
     169        $missing = true;
     170      }
     171      // else ok
     172      else
     173      {
     174        $file_data['stat'] = 'ok';
     175        $ok = true;
     176      }
     177    }
     178    unset($file_data);
     179   
     180    // string is missing if at least missing in one file
     181    if ($missing)
     182    {
     183      $string_data['stat'] = 'missing';
     184      $counts['missing']++;
     185    }
     186    // string is useless if useless in all files
     187    else if ($useless && !$ok)
    130188    {
    131189      $string_data['stat'] = 'useless';
    132190      $counts['useless']++;
    133191    }
    134     else if (!$string_data['in_plugin'] && !$string_data['in_common'] && (!$string_data['is_admin'] || !$string_data['in_admin']))
    135     {
    136       $string_data['stat'] = 'missing';
    137       $counts['missing']++;
    138     }
     192    // else ok
    139193    else
    140194    {
     
    150204  $template->assign(array(
    151205    'PLA_STEP' => 'analysis',
    152     'PLA_PLUGIN' => $_GET['plugin_id'],
    153     'PLA_FILES' => $files,
     206    'PLA_PLUGIN' => $plugins->fs_plugins[ $_GET['plugin_id'] ],
    154207    'PLA_STRINGS' => $strings,
     208    'PLA_LANG_FILES' => $language_files,
    155209    'PLA_COUNTS' => $counts,
    156210    'U_BACK' => PLA_ADMIN.'&amp;plugin_id='.$_GET['plugin_id'],
  • extensions/plugin_lang_analysis/include/functions.inc.php

    r23449 r23467  
    44/**
    55 * list files of a plugin
     6 * @param: string $id, plugin id
     7 * @return: array of paths relative to plugin root
    68 */
    79function list_plugin_files($id, $path=null)
     
    2224  }
    2325 
    24   if (($handle = opendir(PHPWG_PLUGINS_PATH.$id.$path)) === false)
     26  if (($handle = @opendir(PHPWG_PLUGINS_PATH.$id.$path)) === false)
    2527  {
    2628    return array();
     
    5355
    5456/**
     57 * list language files of a plugin
     58 * @param: string $id, plugin id
     59 * @return: array, keys are basenames, values are paths relative to plugin root
     60 */
     61function list_plugin_languages_files($id)
     62{
     63  $path = '/language/en_UK/';
     64 
     65  if (($handle = @opendir(PHPWG_PLUGINS_PATH.$id.$path)) === false)
     66  {
     67    return array();
     68  }
     69 
     70  $data = array();
     71 
     72  while ($entry = readdir($handle))
     73  {
     74    if ($entry=='.' || $entry=='..' || $entry=='.svn' || $entry=='index.php') continue;
     75   
     76    if (!is_dir(PHPWG_PLUGINS_PATH.$id.$path.$entry))
     77    {
     78      $ext = strtolower(get_extension($entry));
     79      if ($ext == 'php')
     80      {
     81        $data[ basename($entry, '.php') ] = $path.$entry;
     82      }
     83    }
     84  }
     85 
     86  closedir($handle);
     87 
     88  return $data;
     89}
     90
     91/**
    5592 * list translated strings of a file
     93 * @param: string $path, file $path relative to main plugins folder
     94 * @return: array, keys are language strings, values are arrays of lines
    5695 */
    5796function analyze_file($path)
     
    113152
    114153/**
     154 * get language files loaded in main.inc.php
     155 * @param: string $id, plugin id
     156 * @return: array of file basenames
     157 */
     158function get_loaded_in_main($id)
     159{
     160  $content = file_get_contents(PHPWG_PLUGINS_PATH.$id.'/main.inc.php');
     161 
     162  $files = array();
     163 
     164  if (preg_match_all('#load_language\((?:\s*)(?:["\']{1})(.*?)(?:["\']{1})#', $content, $matches))
     165  {
     166    $files = $matches[1];
     167  }
     168 
     169  return $files;
     170}
     171
     172/**
    115173 * load a language file
    116174 */
  • extensions/plugin_lang_analysis/template/fontello/config.json

    r23421 r23467  
    88      "css": "ok-squared",
    99      "code": 59394,
     10      "src": "fontawesome"
     11    },
     12    {
     13      "uid": "4ba33d2607902cf690dd45df09774cb0",
     14      "css": "plus-circled",
     15      "code": 59393,
    1016      "src": "fontawesome"
    1117    },
  • extensions/plugin_lang_analysis/template/fontello/css/fontello_pla.css

    r23421 r23467  
    11@font-face {
    22  font-family: 'fontello_pla';
    3   src: url('../font/fontello_pla.eot?40386331');
    4   src: url('../font/fontello_pla.eot?40386331#iefix') format('embedded-opentype'),
    5        url('../font/fontello_pla.woff?40386331') format('woff'),
    6        url('../font/fontello_pla.ttf?40386331') format('truetype'),
    7        url('../font/fontello_pla.svg?40386331#fontello_pla') format('svg');
     3  src: url('../font/fontello_pla.eot?43900030');
     4  src: url('../font/fontello_pla.eot?43900030#iefix') format('embedded-opentype'),
     5       url('../font/fontello_pla.woff?43900030') format('woff'),
     6       url('../font/fontello_pla.ttf?43900030') format('truetype'),
     7       url('../font/fontello_pla.svg?43900030#fontello_pla') format('svg');
    88  font-weight: normal;
    99  font-style: normal;
     
    1515  @font-face {
    1616    font-family: 'fontello_pla';
    17     src: url('../font/fontello_pla.svg?40386331#fontello_pla') format('svg');
     17    src: url('../font/fontello_pla.svg?43900030#fontello_pla') format('svg');
    1818  }
    1919}
     
    5353.iconpla-attention:before { content: '\e804'; } /* '' */
    5454.iconpla-attention-circled:before { content: '\e805'; } /* '' */
     55.iconpla-plus-circled:before { content: '\e801'; } /* '' */
    5556.iconpla-minus-circled:before { content: '\e800'; } /* '' */
    5657.iconpla-ok-squared:before { content: '\e802'; } /* '' */
  • extensions/plugin_lang_analysis/template/fontello/demo.html

    r23421 r23467  
    260260        <div title="Code: 0xe804" class="the-icons span3"><i class="iconpla-attention"></i> <span class="i-name">iconpla-attention</span><span class="i-code">0xe804</span></div>
    261261        <div title="Code: 0xe805" class="the-icons span3"><i class="iconpla-attention-circled"></i> <span class="i-name">iconpla-attention-circled</span><span class="i-code">0xe805</span></div>
     262        <div title="Code: 0xe801" class="the-icons span3"><i class="iconpla-plus-circled"></i> <span class="i-name">iconpla-plus-circled</span><span class="i-code">0xe801</span></div>
    262263        <div title="Code: 0xe800" class="the-icons span3"><i class="iconpla-minus-circled"></i> <span class="i-name">iconpla-minus-circled</span><span class="i-code">0xe800</span></div>
     264      </div>
     265      <div class="row">
    263266        <div title="Code: 0xe802" class="the-icons span3"><i class="iconpla-ok-squared"></i> <span class="i-name">iconpla-ok-squared</span><span class="i-code">0xe802</span></div>
    264267      </div>
  • extensions/plugin_lang_analysis/template/fontello/font/fontello_pla.svg

    r23421 r23467  
    99<glyph glyph-name="attention" unicode="&#xe804;" d="M571 83l0 106q0 8-5 13t-13 5l-107 0q-7 0-13-5t-5-13l0-106q0-8 5-13t13-5l107 0q7 0 13 5t5 13z m-1 209l10 256q0 7-6 11-7 6-13 6l-123 0q-6 0-13-6-6-4-6-12l9-255q0-6 6-9t13-4l103 0q8 0 13 4t6 9z m-8 521l429-786q20-35-1-70-9-16-26-26t-35-9l-857 0q-19 0-35 9t-26 26q-21 35-1 70l429 786q9 17 26 27t36 10 36-10 26-27z" horiz-adv-x="1000" />
    1010<glyph glyph-name="attention-circled" unicode="&#xe805;" d="M429 779q117 0 215-57t156-156 57-215-57-215-156-156-215-57-215 57-156 156-57 215 57 215 156 156 215 57z m71-696l0 106q0 8-5 13t-12 5l-107 0q-7 0-13-6t-6-13l0-106q0-7 6-13t13-6l107 0q7 0 12 5t5 13z m-1 192l10 347q0 7-6 10-6 4-13 4l-123 0q-8 0-13-4-6-3-6-10l9-347q0-6 6-10t13-4l103 0q8 0 13 4t6 10z" horiz-adv-x="857.143" />
     11<glyph glyph-name="plus-circled" unicode="&#xe801;" d="M679 314l0 71q0 15-11 25t-25 11l-143 0 0 143q0 15-11 25t-25 11l-71 0q-15 0-25-11t-11-25l0-143-143 0q-15 0-25-11t-11-25l0-71q0-15 11-25t25-11l143 0 0-143q0-15 11-25t25-11l71 0q15 0 25 11t11 25l0 143 143 0q15 0 25 11t11 25z m179 36q0-117-57-215t-156-156-215-57-215 57-156 156-57 215 57 215 156 156 215 57 215-57 156-156 57-215z" horiz-adv-x="857.143" />
    1112<glyph glyph-name="minus-circled" unicode="&#xe800;" d="M679 314l0 71q0 15-11 25t-25 11l-429 0q-15 0-25-11t-11-25l0-71q0-15 11-25t25-11l429 0q15 0 25 11t11 25z m179 36q0-117-57-215t-156-156-215-57-215 57-156 156-57 215 57 215 156 156 215 57 215-57 156-156 57-215z" horiz-adv-x="857.143" />
    1213<glyph glyph-name="ok-squared" unicode="&#xe802;" d="M382 125l343 343q11 11 11 25t-11 25l-57 57q-11 11-25 11t-25-11l-261-261-118 118q-11 11-25 11t-25-11l-57-57q-11-11-11-25t11-25l200-200q11-11 25-11t25 11z m475 493l0-536q0-66-47-114t-114-47l-536 0q-66 0-114 47t-47 114l0 536q0 66 47 114t114 47l536 0q66 0 114-47t47-114z" horiz-adv-x="857.143" />
  • extensions/plugin_lang_analysis/template/main.tpl

    r23449 r23467  
    6363 
    6464  <p>
    65     You can click the <span class="icon-plus-circled"></span> icon on the left of each string to see where it is located.
     65    You can click the <span class="iconpla-plus-circled"></span> icon on the left of each string to see where it is located.
    6666  </p>
    6767</fieldset>
     
    7171 
    7272  <select name="plugin_id">
    73   {foreach from=$PLA_PLUGINS item=plugin}
    74     <option value="{$plugin.id}">{$plugin.id} ({$plugin.version})</option>
     73  {foreach from=$PLA_PLUGINS item=plugin key=plugin_id}
     74    <option value="{$plugin_id}">{$plugin.name} ({$plugin.version})</option>
    7575  {/foreach}
    7676  </select>
     
    8383{elseif $PLA_STEP=='config'}
    8484{footer_script}{literal}
    85 $('.type-button span').click(function() {
     85$('.switch-button.type span').click(function() {
    8686  $(this).siblings('span').removeClass('active');
    8787  $(this).addClass('active');
     
    9494  }
    9595});
     96$('.switch-button.other span').click(function() {
     97  if ($(this).hasClass('active')) {
     98    $(this).removeClass('active');
     99    $(this).next('input').val('false');
     100  }
     101  else {
     102    $(this).addClass('active');
     103    $(this).next('input').val('true');
     104  }
     105});
    96106{/literal}{/footer_script}
    97107
     
    100110  <legend>{'Select dependencies'|@translate}</legend>
    101111 
    102   <b>{'Plugin language file name'|@translate}</b>
    103   <input type="test" name="filename" value="{$PLA_FILENAME}">
    104   <br><br>
    105  
     112  <table class="files">
     113  <thead>
     114    <tr>
     115      <th></th>
     116      <th>{'Core dependency'|@translate}</th>
     117      <th>{'Local dependencies'|@translate}</th>
     118    </tr>
     119  </thead>
     120 
     121  <tbody>
    106122  {foreach from=$PLA_FILES item=file}
    107     <div class="type-button">
    108       <span class="item common {if not $file.is_admin}active{/if}">{'Common'|@translate}</span><!--
    109       --><span class="item admin {if $file.is_admin}active{/if}">{'Admin'|@translate}</span>
    110       <input type="hidden" name="files[{$file.path}]" value="{if $file.is_admin}true{else}false{/if}">
    111     </div>
    112     {$file.path}<br>
     123    <tr>
     124      <td>{$file.path}</td>
     125      <td>
     126        <div class="switch-button type">
     127          <span class="item common {if not $file.is_admin}active{/if}">{'Common'|@translate}</span>
     128          <span class="item admin {if $file.is_admin}active{/if}">{'Admin'|@translate}</span>
     129          <input type="hidden" name="files[{$file.path}][is_admin]" value="{if $file.is_admin}true{else}false{/if}">
     130        </div>
     131      </td>
     132      <td>
     133        <div class="switch-button other">
     134        {foreach from=$PLA_LANG_FILES item=path key=lang_file}
     135          <span class="item other {if $lang_file|in_array:$file.lang_files}active{/if}">{$lang_file}</span>
     136          <input type="hidden" name="files[{$file.path}][lang_files][{$lang_file}]" value="{if $lang_file|in_array:$file.lang_files}true{else}false{/if}">
     137        {/foreach}
     138        </div>
     139      </td>
     140    </tr>
    113141  {/foreach}
     142  </tbody>
     143  </table>
    114144 
    115145  <p class="formButtons"><input type="submit" value="{'Continue'|@translate}"></p>
     
    120150{elseif $PLA_STEP=='analysis'}
    121151{footer_script}{literal}
    122 $('.strings tr td:first-child').click(function() {
    123   if ($(this).hasClass('icon-plus-circled')) {
    124     $(this).removeClass('icon-plus-circled').addClass('iconpla-minus-circled');
    125     $(this).next().children('ul').show();
     152$('.strings tr.string td.toggler').click(function() {
     153  if ($(this).hasClass('iconpla-plus-circled')) {
     154    $(this).removeClass('iconpla-plus-circled').addClass('iconpla-minus-circled');
     155    $(this).parent().nextUntil('tr.string').show();
    126156  }
    127157  else {
    128     $(this).removeClass('iconpla-minus-circled').addClass('icon-plus-circled');
    129     $(this).next().children('ul').hide();
    130   }
     158    $(this).removeClass('iconpla-minus-circled').addClass('iconpla-plus-circled');
     159    $(this).parent().nextUntil('tr.string').hide();
     160  }
     161});
     162
     163$('.strings tr.string').hover(
     164  function() {
     165    $(this).addClass('hover').nextUntil('tr.string').addClass('hover');
     166  },
     167  function() {
     168    $(this).removeClass('hover').nextUntil('tr.string').removeClass('hover');
     169  }
     170);
     171$('.strings tr.file').hover(
     172  function() {
     173    $(this).prevAll('tr.string:first').addClass('hover').nextUntil('tr.string').addClass('hover');
     174  },
     175  function() {
     176    $(this).prevAll('tr.string:first').removeClass('hover').nextUntil('tr.string').removeClass('hover');
     177  }
     178);
     179
     180$('.open-all').click(function() {
     181  $('.strings tr.file').show();
     182});
     183$('.open-missing').click(function() {
     184  $('.strings tr.file.string-missing').show();
     185});
     186$('.close-all').click(function() {
     187  $('.strings tr.file').hide();
    131188});
    132189{/literal}{/footer_script}
    133190
    134 <fieldset>
    135   <legend>{$PLA_PLUGIN}</legend>
     191{html_style}
     192.strings tr td:nth-last-child(-n+{math equation="2+x" x=$PLA_LANG_FILES|@count}) {ldelim}
     193  text-align:center;
     194}
     195{/html_style}
     196
     197<fieldset>
     198  <legend>{$PLA_PLUGIN.name}</legend>
     199 
     200  <p style="text-align:left;">
     201    <a class="open-all">{'Expand all'|@translate}</a>
     202    / <a class="open-missing">{'Expand missing'|@translate}</a>
     203    / <a class="close-all">{'Collapse all'|@translate}</a>
     204  </p>
    136205 
    137206  <table class="strings">
     
    144213      </th>
    145214      <th>{'Dependency'|@translate}</th>
    146       <th>{'In plugin'|@translate}</th>
    147       <th>{'In common'|@translate}</th>
    148       <th>{'In admin'|@translate}</th>
     215    {foreach from=$PLA_LANG_FILES item=path key=lang_file}
     216      <th>{$lang_file}</th>
     217    {/foreach}
     218      <th>common.lang</th>
     219      <th>admin.lang</th>
    149220    </tr>
    150221  </thead>
     
    152223  <tbody>
    153224  {foreach from=$PLA_STRINGS item=data key=string}
     225    <!-- begin string -->
    154226    <tr class="string {$data.stat}">
    155       <td class="icon-plus-circled"></td>
    156       <td>
    157         {$string|htmlspecialchars}
    158         <ul>
    159         {foreach from=$data.files item=lines key=file}
    160           <li class="text-{if $PLA_FILES[$file].is_admin}admin{else}common{/if}">
    161             {$file} <i>({', '|@implode:$lines})</i></li>
    162         {/foreach}
    163         </ul>
    164       </td>
     227      <td class="toggler iconpla-plus-circled"></td>
     228      <td>{$string|htmlspecialchars}</td>
    165229      {if $data.is_admin}<td class="text-admin">{'Admin'|@translate}</td>
    166230      {else}<td class="text-common">{'Common'|@translate}</td>{/if}
    167       <td>{if $data.in_plugin}<b>{'Yes'|@translate}</b>{else}{'No'|@translate}{/if}</td>
     231    {foreach from=$PLA_LANG_FILES item=path key=lang_file}
     232      <td>{if $lang_file|in_array:$data.in_plugin}<b>{'Yes'|@translate}</b>{else}{'No'|@translate}{/if}</td>
     233    {/foreach}
    168234      <td>{if $data.in_common}<b>{'Yes'|@translate}</b>{else}{'No'|@translate}{/if}</td>
    169235      <td>{if $data.in_admin}<b>{'Yes'|@translate}</b>{else}{'No'|@translate}{/if}</td>
    170236    </tr>
    171   {/foreach}
     237    {foreach from=$data.files item=file_data key=file}
     238      <!-- begin file -->
     239      <tr class="file string-{$data.stat} {$file_data.stat}">
     240        <td></td>
     241        <td>{$file} <i>({', '|@implode:$file_data.lines})</i></td>
     242        {if $file_data.is_admin}<td class="text-admin">{'Admin'|@translate}</td>
     243        {else}<td class="text-common">{'Common'|@translate}</td>{/if}
     244      {foreach from=$PLA_LANG_FILES item=path key=lang_file}
     245        <td>{if $lang_file|in_array:$file_data.lang_files}<b>{'Yes'|@translate}</b>{else}{'No'|@translate}{/if}</td>
     246      {/foreach}
     247        <td></td>
     248        <td></td>
     249      </tr>
     250    {/foreach} {* <!-- end file --> *}
     251  {/foreach} {* <!-- end string --> *}
    172252  </tbody>
    173253 
     
    176256      <th></th>
    177257      <th>{'%d strings : %d missing and %d useless.'|@translate|sprintf:$PLA_COUNTS.total:$PLA_COUNTS.missing:$PLA_COUNTS.useless}</th>
     258      <th></th>
    178259      <th></th>
    179260      <th></th>
  • extensions/plugin_lang_analysis/template/style.css

    r23449 r23467  
    66}
    77   
    8 .type-button {
     8.switch-button {
    99  display:inline-block;
    10   white-space:no-wrap;
    1110
    12   .type-button span {
    13     display:inline-block;
     11  .switch-button span {
     12    float:left;
    1413    padding:5px 8px;
    15     margin:1px;
    1614    background:#e6e6e6;
    1715    color:#555;
    1816    cursor:pointer;
    1917  }
    20     .type-button span.active {
     18    .switch-button span.active {
    2119      color:#212121;
    2220    }
    23     .type-button span.common.active {
     21    .switch-button span.common.active {
    2422      background:#BAFF3F;
    2523    }
    26     .type-button span.admin.active {
     24    .switch-button span.admin.active {
    2725      background:#FF5E5B;
    2826    }
    29     .type-button span:first-of-type {
     27    .switch-button span.other.active {
     28      background:#4CC6FF;
     29    }
     30    .switch-button span:first-of-type {
    3031      border-radius:5px 0 0 5px;
    3132    }
    32     .type-button span:last-of-type {
     33    .switch-button span:last-of-type {
    3334      border-radius:0 5px 5px 0;
    3435    }
    35    
     36    .switch-button span:only-of-type {
     37      border-radius:5px;
     38    }
     39
     40.files {
     41  border-collapse:separate;
     42  border-spacing:10px 0;
     43  text-align:left !important;
     44  margin:0;
     45}
     46
    3647.strings {
    3748  border-collapse:collapse;
     
    6374  .strings td {
    6475    background:#e7e7e7;
    65     border-bottom:1px solid #ccc;
     76    border-top:1px solid #ccc;
    6677    padding:2px 3px;
    6778    vertical-align:top;
     
    7485      background:#DBEACC;
    7586    }
    76     .strings tr:hover td {
     87    .strings tr.hover td {
    7788      background:#D9E2EB;
    7889    }
    7990 
    80   .strings tr td:first-child {
     91  .strings tr td.toggler {
    8192    cursor:pointer;
    8293    color:#666;
    8394  }
    8495    .strings tr td:first-child:hover:before {
    85       color:#222;;
     96      color:#222;
    8697    }
    8798  .strings tr td:nth-child(2) {
     
    89100    max-width:700px;
    90101  }
    91   .strings tr td:nth-last-child(-n+3) {
    92     text-align:center;
    93   }
    94   .strings tr td:nth-last-child(4) {
     102  .strings tr td:nth-child(3) {
    95103    text-align:right;
    96104  }
    97105 
    98   .strings ul {
    99     border-top:1px solid #ccc;
     106  .strings tr.file {
    100107    display:none;
    101     margin:3px 0 3px -3px !important;
    102     padding:3px 0 0 20px !important;
    103     font-family:monospace;
    104     font-size:13px;
     108    font-size:0.8em;
    105109  }
    106     .strings ul li {
    107       margin:0 !important;
    108       line-height:1.5em !important;
    109       list-style:disc;
     110    .strings tr.file td {
     111      border-color:#ddd;
    110112    }
    111113   
Note: See TracChangeset for help on using the changeset viewer.