Views |
8.4x |
hook_views_query_alter |
Viewsクエリの条件式にサブクエリを追加する方法 |
Views |
8.4x |
hook_views_query_alter |
現在のViewsクエリを保存・再現する方法 |
Views Exposed Filter |
8.4x |
hook_views_pre_view |
Views Exposed Formの複数単語入力(textfield)をフォーム上だけ複数行入力(textarea)にする方法 |
Initial |
8.4x |
Subscriber |
hook_init() 〜 drupal_goto() を drupal8でやる方法 |
コンテンツの管理 |
8.4x |
Action |
カスタムアクションを作成する方法 |
SFTP |
8.4x |
SFTP RSA |
SFTP(RSA)でファイル転送(送信)する方法 |
コンテンツの管理 |
8.4x |
Entity |
EntityをPropertyで探す(クエリする)方法 |
コンテンツの作成 |
8.4x |
node |
node保存前に色々やる方法 |
Token |
8.4x |
Token |
カスタムモジュールからtokenを提供する方法(drupal8版) |
コンテンツの作成 |
8.4x |
|
コンテンツ作成時のフォームレイアウトの変更 |
video |
8.4x |
video map |
動画上にクリッカブルマップを作成する方法 |
PHP |
8.3x |
PHP |
drupa8でhook_init()する方法 |
テーマ |
8.3x |
Theme |
drupal8 で パスに応じたページテンプレート名を利用する方法 |
Custom module |
8.3x |
Custom module Twig Block Cache |
カスタムモジュールのレンダリングを非キャッシュ化する方法 |
テーマ |
8.3x |
Block Cache Theme |
管理ページから作成したカスタムブロックを非キャッシュ化する方法 |
テーマ |
8.3x |
Core |
Twig開発用の設定 |
テーマ |
8.3x |
Contribute themes |
drupal8-寄贈テーマの動向 |
拡張機能 |
8.3x |
Contribute modules |
drupal8-寄贈モジュールの動向 |
テーマ |
7.56 |
field |
レンダリング配列内に「ラベル非表示」を指定する方法 |
PhpStorm |
7.50 |
LocalForward |
PhpStormから踏み台を使う |
コメント
たしかに、安全にというのは難しいようです。レンダリング構造
パーマリンク Submitted by actbrain on 2015/07/01 17:37.
たしかに、安全にというのは難しいようです。レンダリング構造(階層)を変更したり、階層を増やす拡張モジュールもいたりと。
参考までに、一番安全かとおもわれるテーブル化を紹介します。
手順は以下のようになります。
1.hook_theme()により、オリジナルラッパーを追加する。
2.追加したオリジナルラッパーを標準ラッパー(form)の直前に実行させる。
3.追加したオリジナルラッパー内で<table> </table>でラップする。
4.hook_form_alter()により、各フィールドフォームを<tr><th>ラベル</th><td>フォーム</td></tr>でラップする。
※ 例えば、本来
〜
<div class="field-type-number-integer field-name-field-price field-widget-number form-wrapper" id="edit-field-price">
<div id="field-price-add-more-wrapper">
<div class="form-item form-type-textfield form-item-field-price-und-0-value">
<label for="edit-field-price-und-0-value">
価格
<span class="form-required" title="このフィールドは必須です。">*</span>
</label>
<input type="text" id="edit-field-price-und-0-value" name="field_price[und][0][value]" value="1000" size="12" maxlength="10" class="form-text required">
<span class="field-suffix">円</span>
</div>
</div>
</div>
〜
なようになっているところを、
〜
<tr>
<th>
価格
<span class="form-required" title="このフィールドは必須です。">*</span>
</th>
<td>
<div class="field-type-number-integer field-name-field-price field-widget-number form-wrapper" id="edit-field-price">
<div id="field-price-add-more-wrapper">
<div class="form-item form-type-textfield form-item-field-price-und-0-value">
<input type="text" id="edit-field-price-und-0-value" name="field_price[und][0][value]" value="1000" size="12" maxlength="10" class="form-text required">
<span class="field-suffix">円</span>
</div>
</div>
</div>
</td>
</tr>
〜
とすることを狙っています。
以下、具体的な処理を示します。
// 1.hook_theme()により、オリジナルラッパーを追加する。
/**
* Implements hook_theme().
*/
function モジュール名_theme() {
return array(
'モジュール名_table_form' => array(
'render element' => 'form',
),
);
}
// 3.追加したオリジナルラッパー内で<table> </table>でラップする。
function theme_モジュール名_table_form($variables) {
$element = $variables['form'];
$prefix = '<table><tbody>'; // クラス等は自由に付ける
$suffix = '</tbody></table>';
return $prefix.$element['#children'].$suffix;
}
/**
* Implement hook_form_alter() {
*/
function モジュール名_form_alter(&$form, $form_state, $form_id) {
// 2.追加したオリジナルラッパーを標準ラッパー(form)の直前に実行させる。
array_unshift($form['#theme_wrappers'], 'モジュール名_table_form');
_モジュール名_erase_title_display($form); //
// 4.hook_form_alter()により、各フィールドフォームを<tr><th>ラベル</th><td>フォーム</td></tr>でラップする。
// フィールド単位の制御
foreach ($form as $field_name => &$field) {
if (strlen($field_name) && strpos($field_name, 0, 1) != '#' && isset($field) && is_array($field) && !empty($field['#type'])) {
$label = $required = $display = $visibility = '';
// 全フィールドを捜査し、$label〜$visibilityを取得
// $label:タイトル
// $required:入力必須
// $display:行そのものの表示有無
// $visibility:th(タイトル)の表示有無
if (isset($field['#type'])) {
if ($field['#type'] == 'container') {
foreach ($field as $n => &$f) {
if (strlen($n) && substr($n, 0, 1) != '#' && isset($f) && is_array($f)) {
if (isset($f['#title'])) {
$label = $f['#title'];
$required = !empty($f['#required']);
break;
}
}
}
}
elseif (isset($field) && is_array($field)) {
if (isset($field['#title'])) {
$label = $field['#title'];
$required = !empty($field['#required']);
}
}
}
if (!empty($required)) {
$label .= '<span class="form-required" title="このフィールドは必須です">*</span>';
}
if (!$label) {
if ($field_name == 'actions') {
$visibility = 'visibility: hidden;';
}
else $display = 'display: none;';
}
// tr.class.// CSS装飾のためtrにクラスを付ける
$tr_class = str_replace('_', '-', $field_name).'-tr';
// th, td.
foreach (array('#prefix', '#suffix') as $type) {
if (!isset($field[$type])) {
$field[$type] = '';
}
}
// ラップ
$field['#prefix'] = str_replace(
array('[tr_class]', '[tr_style]', '[th_style]', '[label]'),
array($tr_class, $display, $visibility, $label),
'<tr class="[tr_class]" style="[tr_style]"><th style="[th_style]">[label]</th><td>'
).$field['#prefix'];
$field['#suffix'] .= '</td></tr>';
}
}
}
// フォーム内の全てのタイトルを'invisible'にする(再帰的)
function _モジュール名_erase_title_display(&$form) {
if (isset($form) && is_array($form)) {
foreach ($form as $field_name => &$field) {
if (strlen($field_name) && substr($field_name, 0, 1) != '#' && isset($field) && is_array($field)) {
if (isset($field['#title'])) {
$field['#title_display'] = 'invisible';
}
_モジュール名_erase_title_display($field);
}
}
}
}
ページ