ノード編集フォームをテーブル表示形式にしたい

カテゴリ コンテンツの作成 コアバージョン 7.38 関連モジュール node form

Drupalのノード編集フォームは
タイトル:
[          ]
のような形になっており、どうも日本人にはしっくり来ません。
特に、編集者のリテラシーが低い場合はなかなかうまくゆきません。
CSSでテーブルライクな表示にしたり、テンプレートの中でレンダリング調整したりしましたが、利用しているテーマに手を入れられなかったり、他のフィールド系モジュールを追加すると表示が崩れてしまったりして、なかなかうまくいきません。
なんとか安全に日本人好みのテーブル表示の形式にできないでしょうか?

コメント

ユーザー actbrain の写真

たしかに、安全にというのは難しいようです。レンダリング構造(階層)を変更したり、階層を増やす拡張モジュールもいたりと。
参考までに、一番安全かとおもわれるテーブル化を紹介します。
手順は以下のようになります。

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);
}
}
}
}

ページ

OTHER FAQ

Drupal開発・運用の疑問/質問の答えはここに

無料ユーザー登録すると質問できます。

カテゴリ降順で並び替える Core Ver. 関連モジュール タイトル
ダウンロード 6.x Views Bonus Pack Viewsで表示した内容をCSVダウンロード
チューニング 7.26 PHP DrupalはNginxで動く?
テーマ 8.4x hook_preprocess_html bodyタグにnode idやaliasのClassを追加する方法
テーマ 8.3x Theme drupal8 で パスに応じたページテンプレート名を利用する方法
テーマ 8.9.x Twig Twig で 月末日を算出する方法
テーマ 8.3x Core Twig開発用の設定
テーマ 7.34 スマホ、PCおよびアプリを同時に運用可能なおすすめのテーマはありますでしょうか?
テーマ 8.9.x patch パッチ 開発環境のファイル変更を本番環境にパッチでデプロイする方法(画像含まず)
テーマ 8.7.x Bartikのtwigについて
テーマ 7.56 field レンダリング配列内に「ラベル非表示」を指定する方法
テーマ 8.9.x スマホに向いたテーマについて
テーマ 7.23 hook ページや状況によってテーマを切り替える
テーマ 8.3x Block Cache Theme 管理ページから作成したカスタムブロックを非キャッシュ化する方法
テーマ 7.15 CSS Injector 簡単にCSSを追加したい
テーマ 8.3x Contribute themes drupal8-寄贈テーマの動向
ニュースレター 7.34 Simple news Simplenewsで追加顧客(リスト)だけにニュースレターを配信する方法
パフォーマンス 7.34 Server お金をかけないで冗長化するには
フォーム 7.15 Webform Webformで確認画面
フォーム 7.15 Webform Webform - 確認ページの多言語化
フォーム 7.15 system mail()での送信が失敗する

ページ