Skip to content

Commit

Permalink
Merge pull request fc2blog#368 from uzulla/issue339/build-html-by-twig
Browse files Browse the repository at this point in the history
文字列連結でおこなっているInputタグ生成を、Twigで書き換え fc2blog#339
  • Loading branch information
fc2dev authored Sep 16, 2021
2 parents 96cd651 + 93055b0 commit 9bb1ac7
Show file tree
Hide file tree
Showing 15 changed files with 276 additions and 68 deletions.
27 changes: 17 additions & 10 deletions app/src/Service/TwigService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,26 @@ public static function getTwigBasePath(): string
return static::TWIG_TEMPLATE_BASE_PATH;
}

static $twigInstance = null;

public static function getTwigInstance(): Environment
{
$loader = new FilesystemLoader(static::getTwigBasePath());
$twig = new Environment($loader);

foreach (
array_merge(
(new GetTextHelper())->getFunctions(),
(new HtmlHelper())->getFunctions(),
) as $function) {
$twig->addFunction($function);
if (is_null(static::$twigInstance)) {

$loader = new FilesystemLoader(static::getTwigBasePath());
$twig = new Environment($loader);

foreach (
array_merge(
(new GetTextHelper())->getFunctions(),
(new HtmlHelper())->getFunctions(),
) as $function) {
$twig->addFunction($function);
}

static::$twigInstance = $twig;
}

return $twig;
return static::$twigInstance;
}
}
98 changes: 40 additions & 58 deletions app/src/Web/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Fc2blog\App;
use Fc2blog\Model\BlogsModel;
use Fc2blog\Service\TwigService;
use Fc2blog\Util\StringCaseConverter;

class Html
Expand Down Expand Up @@ -156,7 +157,7 @@ public static function input(Request $request, $name, $type, $attrs = array(), $
$rvalue = $request->get($r_name, $default);

// 属性作成
$attrs['name'] = ($type == 'checkbox' && count($options)) ? $name . '[]' : $name;
$attrs['name'] = ($type == 'checkbox' && count($options) > 0) ? $name . '[]' : $name;
$attr = array();
foreach ($attrs as $key => $value) {
$attr[] = $key . '="' . $value . '"';
Expand All @@ -173,101 +174,82 @@ public static function input(Request $request, $name, $type, $attrs = array(), $

// HTMLを作成
$html = '';

$twig = TwigService::getTwigInstance();

switch ($type) {
default:
$html = '<span>[' . $type . ']は未実装です</span>';
$html = $twig->render('fragment/undefined.twig', ['type' => $type]);
break;

case 'text':
$html = '<input type="text" ' . $attr . ' value="' . h((string)$rvalue) . '" />';
$html = $twig->render('fragment/text.twig', ['attr' => $attr, 'rvalue' => $rvalue]);
break;

case 'password':
$html = '<input type="password" ' . $attr . ' value="' . h((string)$rvalue) . '" />';
$html = $twig->render('fragment/password.twig', ['attr' => $attr, 'rvalue' => $rvalue]);
break;

case 'blank_password':
// 一方向に設定するので、表示しない
$html = '<input type="password" ' . $attr . ' />';
$html = $twig->render('fragment/password.twig', ['attr' => $attr, 'rvalue' => '']);
break;

case 'file':
$html = '<input type="file" ' . $attr . ' />';
$html = $twig->render('fragment/file.twig', ['attr' => $attr]);
break;

case 'hidden':
$html = '<input type="hidden" ' . $attr . ' value="' . h((string)$rvalue) . '" />';
$html = $twig->render('fragment/hidden.twig', ['attr' => $attr, 'rvalue' => $rvalue]);
break;

case 'token':
$html = '<input type="hidden" ' . $attr . ' value="' . h(Session::get($name)) . '" />';
case 'token': // TODO すでに使われていないのではないか?
$html = $twig->render('fragment/hidden.twig', ['attr' => $attr, 'rvalue' => Session::get($name)]);
break;

case 'captcha':
$html = '<input type="text" ' . $attr . ' value="" />';
$html = $twig->render('fragment/text.twig', ['attr' => $attr, 'rvalue' => ""]);
break;

case 'textarea':
$html = '<textarea ' . $attr . '>' . h((string)$rvalue) . '</textarea>';
$html = $twig->render('fragment/textarea.twig', ['attr' => $attr, 'rvalue' => $rvalue]);
break;

case 'select':
$html = '<select ' . $attr . '>';
foreach ($options as $key => $option) {
if (is_array($option)) {
// オプショングループ付きSelect
if (!isset($option['value'])) {
$html .= '<optgroup label="' . $key . '">';
foreach ($option as $k => $v) {
$html .= '<option value="' . $k . '" ' . ($rvalue !== null && $k == $rvalue ? 'selected="selected"' : '') . '>' . h($v . $suffix) . '</option>';
}
$html .= '</optgroup>';
continue;
}
// 属性付きオプション
$optionAttr = ($rvalue !== null && $key == $rvalue ? 'selected="selected"' : '');
if (!empty($option['disabled'])) {
$optionAttr .= ' disabled="disabled" ';
}
$html .= '<option value="' . $key . '" ' . $optionAttr . '>' . str_repeat('&nbsp;&nbsp;&nbsp;', $option['level'] - 1) . h($option['value'] . $suffix) . '</option>';
} else {
// 通常のオプション
$html .= '<option value="' . $key . '" ' . ($rvalue !== null && $key == $rvalue ? 'selected="selected"' : '') . '>' . h($option . $suffix) . '</option>';
}
}
$html .= '</select>';
$html = $twig->render('fragment/select.twig', [
'attr' => $attr,
'rvalue' => $rvalue,
'suffix' => $suffix,
'option_list' => $options,
]);
break;

case 'radio':
$labelKey = 'sys-radio-' . str_replace(array('[', ']'), array('-', ''), $name) . '-';
$html .= '<ul class="form-radio-list">';
$li_attr = isset($option_attrs['li']) ? ' ' . $option_attrs['li'] : '';
$label_attr = isset($option_attrs['label']) ? ' ' . $option_attrs['label'] : '';
foreach ($options as $key => $option) {
$html .= '<li' . $li_attr . '>';
$html .= ' <input type="radio" value="' . $key . '" ' . ($key == $rvalue ? 'checked="checked"' : '') . ' ' . $attr . ' id="' . $labelKey . $key . '" />';
$html .= ' <label for="' . $labelKey . $key . '" ' . $label_attr . '>' . $option . '</label>';
$html .= '</li>';
$labelKey = 'sys-radio-' . str_replace(['[', ']'], ['-', ''], $name) . '-';
$li_attr = $option_attrs['li'] ?? '';
$label_attr = $option_attrs['label'] ?? '';
$is_checked_key_list = [];
if (is_array($rvalue)) {
foreach ($options as $key => $option) {
if (in_array($key, $rvalue)) {
$is_checked_key_list[] = $key;
}
}
}
$html .= '</ul>';
$html .= $twig->render('fragment/ul.twig', ['attr' => $attr, 'rvalue' => $rvalue, 'option_list' => $options, 'label_key' => $labelKey, 'li_attr' => $li_attr, 'label_attr' => $label_attr, 'is_checked_key_list' => $is_checked_key_list]);
break;

case 'checkbox':
if (count($options)) {
$labelKey = 'sys-checkbox-' . str_replace(array('[', ']'), array('-', ''), $name) . '-';
$rvalue = is_array($rvalue) ? $rvalue : array();
$labelKey = 'sys-checkbox-' . str_replace(['[', ']'], ['-', ''], $name) . '-';
$rvalue = is_array($rvalue) ? $rvalue : [$rvalue];
$is_checked_key_list = [];
if (is_array($rvalue)) {
foreach ($options as $key => $option) {
$html .= '<input type="checkbox" value="' . $key . '" ' . (in_array($key, $rvalue) ? 'checked="checked"' : '') . ' ' . $attr . ' id="' . $labelKey . $key . '" />';
$html .= '<label for="' . $labelKey . $key . '">' . $option . '</label>';
}
} else {
$labelKey = 'sys-checkbox-' . str_replace(array('[', ']'), array('-', ''), $name);
$is_checked = $rvalue !== null && isset($attrs['value']) && $attrs['value'] == $rvalue;
$html .= '<input type="checkbox" ' . ($is_checked ? 'checked="checked"' : '') . ' ' . $attr . ' id="' . $labelKey . '" />';
if ($label) {
$html .= '<label for="' . $labelKey . '">' . $label . '</label>';
if (in_array($key, $rvalue)) {
$is_checked_key_list[] = $key;
}
}
}
$html = $twig->render('fragment/checkbox.twig', ['attr' => $attr, 'rvalue' => $rvalue, 'option_list' => $options, 'label_key' => $labelKey, 'is_checked_key_list' => $is_checked_key_list]);
break;
}

Expand Down
1 change: 1 addition & 0 deletions app/twig_templates/fragment/checkbox.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% for key, option in option_list %}<input type="checkbox" value="{{ key }}" {% if key in is_checked_key_list %}checked="checked"{% endif %} {{ attr|raw }} id="{{ label_key }}{{ key }}" /><label for="{{ label_key }}{{ key }}">{{ option }}</label>{% endfor %}
1 change: 1 addition & 0 deletions app/twig_templates/fragment/file.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input type="file" {{ attr|raw }} />
1 change: 1 addition & 0 deletions app/twig_templates/fragment/hidden.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input type="hidden" {{ attr|raw }} value="{{ rvalue }}"/>
4 changes: 4 additions & 0 deletions app/twig_templates/fragment/li.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<li {{ li_attr }}>
{% include "fragment/radio.twig" %}
{% include "fragment/radio_label.twig" %}
</li>
1 change: 1 addition & 0 deletions app/twig_templates/fragment/password.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input type="password" {{ attr|raw }} value="{{ rvalue }}"/>
1 change: 1 addition & 0 deletions app/twig_templates/fragment/radio.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input type="radio" value="{{ key }}" {% if key in is_checked_key_list %}checked="checked"{% endif %} {{ attr|raw }} id="{{ label_key }}{{ key }}"/>
1 change: 1 addition & 0 deletions app/twig_templates/fragment/radio_label.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<label for="{{ label_key }}{{ key }}" {{ label_attr|raw }}>{{ option }}</label>
24 changes: 24 additions & 0 deletions app/twig_templates/fragment/select.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<select {{ attr|raw }}>
{% for key, option in option_list %}
{% if option is iterable %}
{% if value in option %}
<optgroup label="{{ key }}">
{% for k, v in option %}
<option value="{{ k }}" {% if k == rvalue %}selected="selected"{% endif %}>{{ v }}{{ suffix }}</option>;
{% endfor %}
</optgroup>
{% else %}
<option value="{{ key }}"
{% if rvalue == key %}selected="selected"{% endif %}
{% if option.disabled %}disabled="disabled"{% endif %}>
{% if option.level>1 %}
{% for i in range(1, option.level-1) %}&nbsp;&nbsp;&nbsp;{% endfor %}{# 字下げ #}
{% endif %}
{{ option.value }}{{ suffix }}
</option>
{% endif %}
{% else %}
<option value="{{ key }}" {% if rvalue == key %}selected="selected"{% endif %}>{{ option }}{{ suffix }}</option>
{% endif %}
{% endfor %}
</select>
1 change: 1 addition & 0 deletions app/twig_templates/fragment/text.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input type="text" {{ attr|raw }} value="{{ rvalue }}"/>
1 change: 1 addition & 0 deletions app/twig_templates/fragment/textarea.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<textarea {{ attr|raw }}>{{ rvalue }}</textarea>
5 changes: 5 additions & 0 deletions app/twig_templates/fragment/ul.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<ul class="form-radio-list">
{% for key, option in option_list %}
{% include "fragment/li.twig" with {key: key} %}
{% endfor %}
</ul>
1 change: 1 addition & 0 deletions app/twig_templates/fragment/undefined.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<span>{{ type }}は未実装です</span>
Loading

0 comments on commit 9bb1ac7

Please sign in to comment.