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

カテゴリ コンテンツの作成 コアバージョン 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. 関連モジュール タイトル昇順で並び替える
アップデート 8.9.x composer patch patch を composer に 組み込む方法
アップデート 7.28 Views Pagerが表示されなくなった
コンテンツの作成 8.4x node node保存前に色々やる方法
言語 7.15 Entity Translation nodeのEntity Translation
フォーム 7.15 system mail()での送信が失敗する
mac linux ファイル名 文字化け 8.7.x mac linux ファイル名 文字化け Macからlinuxにrsyncするとファイル名(濁点)が文字化けする場合の対応方法
コンテンツの作成 8.4x json jQueryにjsonで渡す方法
jQuery Revolution 7.50 jQuery Revolutionのリンクがスマホで機能しない
サイト情報 8.4x JavaScript JavaScriptに変数を渡す方法
GoogleMaps 7.28 Javascript IE9でGoogle Map APIを利用した住所情報所得がうまくゆかない
Initial 8.4x Subscriber hook_init() 〜 drupal_goto() を drupal8でやる方法
Google 7.38 robots.txt Google Search Console Teamから「CSS および JS ファイルに Googlebot がアクセスできません」
Gmian 8.8.x Gmail Gmail:外部メールサーバー経由のメール送信ができなくなった場合の対処方法
フォーム 8.9.x api GET/POSTされた情報を得る方法
表示 7.34 Views Infinite Scroll Facebookページのようにスクロールするとコンテンツが追加されるようなコントロール
コンテンツの作成 8.4x PhpSpreadsheet Excelを読み書きする方法
コンテンツの管理 8.4x Entity EntityをPropertyで探す(クエリする)方法
サイトの構築 7.34 ECK Entityの使い方について
drush 7.54 Drush Drushでdrupalサイトをインストールする方法
アップデート 7.34 Distribution(Commerce Kickstart) drushでcommerce_kickstartのアップデートに失敗する

ページ