1つのコンテンツタイプの複数ノードに、同一のWebformを結びつける

Events happening in the community are now at Drupal community events on www.drupal.org.
s-jack's picture

このところ質問ばかりですみません。
色々と探しまわり、モジュールを翻訳し、また当グループの過去スレを読んでいるのですが、出口が見えないのでアドバイスをお願いします。

1つのコンテンツタイプ(例:作品例)の複数ノードに、同一のWebformのノード(例:作品例専用お問合せフォームを1つだけ作ったとして)を結びつけ、作品例専用お問合せフォームのフィールドに作品例ノードのタイトルとかを自動挿入したいと思います。
また、作品例のノードで、作品例専用お問合せフォームをどのように表示するか、悩んでいます。

<結びつけ>
webformの基本的使い方に慣れていないのですが、コンテンツタイプのデフォルトwebformにコンテンツの作成で複数のウェブフォームを作れますよね。
webformの設定では、他のコンテンツタイプにもウェブフォームを作れますが、他のコンテンツタイプ個々に新たなウェブフォームのフィールドやメールの設定を作らないといけなく、これは個々に異なったウェブフォームを作れる自由度はありますが、同一のウェブフォームを適用するのには大変な作業なため、Webform Templateをインストールし、個々のノードにテンプレートを適用することで同一のウェブフォームをコピーで添付するようなイメージで実現することができました。
しかしながら、個々のノードにウェブフォームがありますので、数が多くなると管理がかなり煩雑です。
また、UIタブに「ウェブフォーム」タブが自動で表示されますが、「お問合せ」のようにタブも変更したくUIタブも変更できなさそうですし、デザイン的にノード内にクイックタブのような感じで作りたいと思っていますので、webformモジュールの他のコンテンツタイプに使う設定はやめたいと思っています。

このグループの過去スレ参考はありましたが、ノードとフォームを結びつけるのをなんとかコードを書かずにやりたく
Node Embedというのを試していたりもします。
作品例専用お問合せフォームのフィールドに、作品例のノードのタイトルなどを自動挿入するのですが、ノードに埋込んだウェブフォームと捉えると、どっちのTakenを使うのかも混乱中ですし、その方法もわかりません。

<ノードでのウェブフォームの表示方法>
webformの場合UIタブに表示されてしまいますので、Quicktabモジュールのように、ノード内にデザインされた箇所にウェブフォームを表示することはコードを書かずに可能でしょうか。

結構事例があると思うのですが、コード書かないとだめですかね。
長々とすみませんが、よろしくお願いします。

参考過去スレ:
webformのデザイン作成について
Webform にて問い合わせページを作成

Comments

Node referenceなんてどうでしょう?

nobuyuki3's picture

Node referenceでやりたい事に近いような気もします。
既にこちらは試されたでしょうか?
私は試した事がないので申し訳ないですが、ご参考までに。

Node Reference URL Widget
http://drupal.org/project/nodereference_url

http://drupal.org/node/845002

見当違いでしたら、ごめんなさい。

nobuyuki3さん、こんにちは。 References

s-jack's picture

nobuyuki3さん、こんにちは。
Referencesモジュールの子モジュールNode referenceは試しておりましたが、Node Reference URL Widgetは試してませんでした。

http://drupal.org/node/845002 のスレッドにスクリーンキャストがあり、それも見てみると、WIEWSを使ったノード対ノードを関連付けてフィルターしたりとか便利ですね。
でもウェブフォーム側を一覧系の結びつけにしたいわけではないので(作品紹介ノード対ウェブフォーム=多対1)ちょっと違うような気がしています。
翻訳しながら弄ってみますが、Widgetタイプの[[http://drupal.org/project/nodereference_url|Node Reference URL Widget]]は便利そうなので、これが使えそうであればレポさせていただきます!

実現したいことと合うかわかりませんが

qchan's picture

実現したいことが
1)あるコンテンツタイプAのページに既存のWebform Bの問い合わせフォームを表示したい。
(コンテンツタイプ(A)と、Webform(B)は別のコンテンツタイプです。)
2)Webformの特定フィールドにそのページのタイトルをデフォルト表示させたい。

で代替できるとして

1)に関してはWebformをBlock化して、Regionの何処かに呼び出せばよいのではないでしょうか。

WebformNodeの設定画面に「Form settings」というタブがあります。
一番下に「SHOWADVANCED SETTINGS」の欄があって
「Available as block」にチェックを入れるとBlock管理画面から任意のリージョンに呼び出せます。
コンテンツリージョンの下などに呼び出せば、Nodeの下に表示されブロックの設定から特定の
コンテンツタイプにだけ表示する設定も可能です。
(注意としては、ブロック化したばあいWebformのNode bodyは表示されません。フォームだけがブロックになります。
bodyも呼び出したい時は新規ブロックを作りPHP filterを使って、WebformのNode全体を呼び出す方法もあります)

2)に関してはform APIを使ってのモジュールを作成すれば比較的簡単なのですが、
コードを書かずに済む方法はパッと思いつかないです。
Tokenを使っての%titleは元のWebformのタイトルを持ってきてしまいますね。

s-jack's picture

qchanさんいつもありがとうございます。

仰せのとおりブロックでできました!モジュールばかり探していて、ブロックの機能を忘れとりました^^;
webformのブロック設定は、表示モード「フォームのみ」、「完全なノード」、「ティーザー」が3つありました。

「フォームのみ」の場合は、おっしゃるとおりNode bodyが表示されません。Node タイトルも表示されなく、リンクでwebformへも飛ばないのでフォームのみとけ込んでいる感じですね。

「完全なノード」の場合は、ブロックのタイトルとwebformのタイトルが2重になるので、ブロックのタイトルにnoneを挿入しましたが、webform nodeのタイトルにリンクが貼られて、webform自体に飛んでしまいます。
Takenを利用できたにせよ、ページが変わるのはよろしくないと予想。

ブロックの場合、ブロック側から見た、主たるノード(コンテンツ)のフィールド値をトークンを拾えないでもんですね。
この辺を実現しているモジュールを探してみますが、無理ならばコードにするしかないですね。

s-jack's picture

webformをブロックで表示しておいて、ノードコンテンツのタイトルを取得するべく、webformのフィールドをmarkupを作り、そこに
<? php print $node->title; ?>を挿入してみましたが、こんな簡単にうまくいくわけないか^^;

Notice: Undefined variable: node eval() (/var/www/html/drupal/modules/php/php.module(80) : eval()'d code ファイル 1行).
Notice: Trying to get property of non-object eval() (/var/www/html/drupal/modules/php/php.module(80) : eval()'d code ファイル 1行).

と怒られました。
ブロックから主たるコンテンツのノードをなんで簡単に取得できないんだろう〜^^;

s-jack's picture

tokenを利用しての話題がありました。
Getting node tokens into Webform block

やっぱモジュール化しなきゃいけないのかな...

こんにちは、s-jackさん私も不動産の問い合わせページ

jun784's picture

こんにちは、s-jackさん

私も不動産の問い合わせページで同じような事をしていますが、
その際は以下のようなhookを作成して対応致しました。

以下をthemeのtemplate.phpに追記してみてください。

template.php

<?php
/**
* Implementation of hook_form_alter().
*/
function {template_name}_form_alter(&$form, &$form_state, $form_id) {
  if (
$form_id == "webform_client_form_{webform_number}") {
   
$form['submitted']['{item_name}']['#default_value'] = arg(1); // 表示しているページのnode_idを取得
 
}
}
?>

**追記

失礼しました、
参照先のURLにすでにこの方法が記載されていましたね。

webform側からだと、
他にも提示されているように、
itemをhiddenにしてdefault valueに
"%get[q]"などでnodeのurlを取得するぐらいでしょうか。

webformから表示しているページのノード情報を取得できないのは、
同じページに出力されているけれど、元の"枝"が違うからになります。

そのあたりはdrupalのhook構造の仕様とも言えるかもしれません。

s-jack's picture

jun784さん、こんにちは。
ありがとうございます。

すみません、このtemplate.phpに追加するfookですが、これをどう利用したらよいでしょうか。
ご教示いただいたコード、またリンク先の使い方がまだ理解できれません^^;

%get[q]についてですが、これはscreecastで教えてもらって使ってます。
問い合わせ元のURIを記録しておくことは重宝するのですが、
ノードのタイトル(ノードのフィールドのいくつかとか)をぜひ挿入したいんですよね〜。
手取り足取りスミマセン。

追記:nodeIDが取得できるってことは、titleも取得できるってこと考え方であってます??

menu_get_object() を試してください。

qchan's picture

一度これで出来るか試してください。私の環境では親のNode情報が取れました。
モジュールに書いても、テーマ内のtemplate.phpに書いてもOKですよ。
{module名かtheme名} と {使いたいWebformのID} のように {} で囲んである2つの部分を自分の環境に置き換えてください。
例えば theme名が jackだったら以下のようにします。

function jack_form_alter(&$form,&$form_state,$form_id){、、、、、、

+++++++++++++++++++++++++++

function {module名かtheme名}_form_alter(&$form,&$form_state,$form_id){
  if($form_id == "webform_client_form_{使いたいWebformのID}"){
  $node  = menu_get_object();
    if ( !empty($node) ) {
      $node_title = $node->title;
       $form['submitted']['title_test']['#default_value'] = $node_title;
    }  
  }
}
s-jack's picture

qchanさん、こんばんは、ありがとうございます。
モジュールでもテーマでもfookできるのがdrupalなんでしょうね。

さっそくtemplate.phpのほうで試したいのですが、
すみません、これをトークンで使うのでしょうか、
webformのフィールドのmarkupでどのようなphpコード書くのでしょうか。

この方法ではトークンは使わないです。

qchan's picture

Webformのフィールドには何も書く必要はありませんよ。
デフォルトの文字列として自動的に親Nodeのタイトルを引っ張ってきます。

さきほどの貼り付けで抜けていましたが、
Nodeのタイトルを引っ張って来たいコンポーネントのフィールドキーを {WebformのField Key} の部分に置き換えて、template.phpへ貼ってください。
計3箇所、自分の環境にあわせて書き換えることになります。
あとは、そのまま貼れば出ると思います。

(すでにtemplate.php内でform_alter() を使っていたら、hook_form_FORM_ID_alter()を使ったほうがいいかもですがとりあえず。)

function {module名かtheme名}_form_alter(&$form,&$form_state,$form_id){
  if($form_id == "webform_client_form_{使いたいWebformのID}"){
  $node  = menu_get_object();
    if ( !empty($node) ) {
      $node_title = $node->title;
       $form['submitted']['{WebformのField Key}']['#default_value'] = $node_title;
    }  
  }
}
s-jack's picture

qchanさん、完璧です。
違うフィールドも引っ張れますね、そしてテンプレートですみますし、違うフォームもフォームIDかえれば良いんですね。
ありがとうございます。m(__)m

話はそれますが、今気がつきましたが、webformも1つのノードなんですね。
また、ブロックのウェブフォームってバリデーションでチェックはいると、ブロックではなくウェブフォームのノードに表示が切り替わってしまうんですね^^;(クライアントバリデーションなんてのもありますので試してみますが)
なおさらどこの問い合わせかデータを引っ張れることはとても重宝します。

Qchanさん コードの補足など、説明不足なのを丁寧に拾っ

jun784's picture

Qchanさん

コードの補足など、説明不足なのを丁寧に拾って頂き、
ありがとうございます!
助太刀いたす。と思いきや、助太刀されてしまいました。

S-jackさん

フォーム部分はDrupalの中でも特に複雑な部分で難しいですので、
またご不明な点があれば気軽にご質問ください。

がんばってくださいね!

s-jack's picture

jun784さんも、ありがとうございました。
とても優しいお言葉、心にしみますよ。^^

徐々にAPI(諸関数)の雰囲気がわかってきましたが、まだまだです。
APIを知らなければDrupalを深くは理解できませんね、またドキュメントが英語ですらすら読めないもんで、翻訳してみたり、あっち調べたりこっちいったりで、頭に入らず困ったちゃんです。
引き続き甘えさせてください。

FormAPIって難しいですよね。

qchan's picture

>> jun784
いつも助けてもらってます。
ThemeのカスタマイズでFormAPIが自由に扱えると非常に強力なんですが、難しいですねー。
theme(), preprocess() ,process() などと合せてわかりやすく学習できたらDrupalの普及にも役立つと思うんですね。
まずは、ありもののテーマやBase Themeのカスタマイズから入るはずなので。

どこからでも、Hackせずに他のモジュールやThemeが吐き出すHTMLをオーバーライド出来るようにという発想が
何層にもレイヤーが重なるテーマ周りの複雑さを生んでいるような気がしますが、痛し痒しですね。

日本のCMSにはDreamweaver(PHP&MySQLが動かない状態)でのテンプレート制作が可能な仕組みを持ったものがあります。
Drupalのコアデベロッパーにも、改善しようといろいろ考えている人たちがいるので、
参考にしてもらえるようにアピールしたいのですが、議論に参加するのが難しくて歯がゆいです。

Let's Do Something About Drupal's Theme System - jacine
A new theme layer for Drupal 8 | Chapter Three

日本 コミュニティ: Drupal Japan User Group

Group organizers

Group categories

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week