Çalışan bir Alan Widget Formunu kendi başına görüntülemek mümkün mü?


21

Tüm düğüm düzenleme formunun içeriğine bir Alan Widget Formu yerleştirmekle ilgileniyorum.

Geçmişte drupal_get_form kullanarak tam formlar gösterdim, ancak bu yalnız Alan Formları için geçerli görünmüyor.

Çalışan bir Alan Widget Formu görüntülemek mümkün mü? Bunu yapmanın en iyi yolu ne olurdu?

Hem alan widget'ları hem de "normal" formlar birbirine benziyor, bu mümkün değilse, bir widget formunu normal forma "değiştirmek" için ne gerekir?

Bu soru benzer bir şey istiyor gibi görünüyor ama cevabı anlamıyorum. Bu cevap hook_field_widget_form_alter kullanarak belirtir ; anlamadığım şey, Alan Formunun nasıl gösterileceğini, oluşturulduktan sonra nasıl bağlanacağını değil.

Yanıtlar:


18

VBO modified.action.inc dosyasında böyle bir şey yapar:

$form_key = 'bundle_' . $bundle_name;
$form[$form_key] = array(
  '#type' => 'fieldset',
  '#title' => $label,
  '#parents' => array($form_key),
);  
field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, LANGUAGE_NONE);  

Öyleyse varlık türüne, öğeye (yalnızca paket anahtar kümesiyle boş bir nesne olabilir, gerçekte kullanılan budur), araçların eklendiği form ve dile ihtiyacınız var. Widget'ları forma daha derine gömmek istiyorsanız ($ biçiminde değil, ancak $ biçiminde [$ form_key] yaptığım gibi, hatta daha derine), o form dizisinin #parents ayarlaması gerekir.

Tabii ki, bunun varlık tipine ve paketine ait tüm alanların widget'larını yerleştireceğine dikkat edin. Ataşman işlevleri böyle yazılmıştır. Bunu çözmek, oldukça fazla sayıda kodu yeniden icat etmenizi gerektirir; ağır kaldırma yapan gerçek kodu görün . Yaptığım şey alan örneklerine bakmak, her $ alan_adı'nı almak ve bu alan türü beni ilgilendirmiyorsa, $form[$form_key][$field_name]['#access'] = FALSE; bu gereçleri görünüşte gizleyen bir set oluşturdum.

EDIT: Tamam, ctools, teorik olarak alan başına çalışmanıza izin verebilecek ctools_field_invoke_field () 'a sahip. Yine de hiç kullanmadım. Yukarıdaki metin benim doğrudan tecrübem.


Müthiş cevap. Bir günün daha iyi bir kısmını bununla çalışarak geçirdim ve istediğim gibi çalıştı. Ödül aldı ve OP'nin bunu doğru cevap olarak kabul etmesini öneriyorum. Sahte bir içerik türü oluşturmaya başladım, böylece #access = FALSEbu bağlamda rahatsız edici görünen bir ayar yerine, alanlarımı diğer içerik türleri gibi kontrol edebilirim .
Letharion

Nelerden korktuğumu onayladığın için teşekkürler: tek alanlı widget'ın pratikte kendi başına kullanılamaması.
SMTF

7

Yoğun bir şekilde ttk tarafından önerilen işlevi kullanıyordum, ancak yakın tarihli bir güncellemenin işleri berbat ettiğini düşünüyorum ...

İşte Drupal 7.22 ve ctools 7.x-1.3 ile iyi çalışan önceki çözümün yeni bir versiyonu.

Böylece, önceki yazıdaki gibi, özel işlevinizi şöyle adlandırırsınız:

my_field_attach_form('field_body', 'node', 'blog',  $node, $form, $form_state, LANGUAGE_NONE);

Varlık paketinin artık bir parametre olduğuna dikkat edin . Bunu yaptım çünkü bu fonksiyonu kullanıcıları düzenlemek için de kullanıyordum. Bu şekilde, taksonomi terimi veya başka herhangi bir varlık için de kullanılabilir.

Ve my_field_attach_formşöyle tanımlanır:

function my_field_attach_form($field_name, $entity_type, $bundle, $entity, &$form, &$form_state, $langcode = NULL) {

  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );

  // Append to the form
  ctools_include('fields');
  $field_instance = field_info_instance($entity_type, $field_name, $bundle);
  $form += (array) ctools_field_invoke_field($field_instance, 'form', $entity_type, $entity, $form, $form_state, $options);
}

Bu fonksiyon bana zaman kazandırdı, umarım sizin için de öyledir!


5

İşte ctools_field_invoke_field()yöntemi kullanarak çözüm . Özel form işlevinizde şunu ekleyin:

$form = array();
$node = new stdClass();
$node->type = 'blog';
my_field_attach_form('field_body', 'node', $node, $form, $form_state, LANGUAGE_NONE);

burada my_field_attach_formişlev olarak tanımlanır

function my_field_attach_form($field_name, $entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );
  module_load_include("inc","ctools","includes/fields");
  $form += (array) ctools_field_invoke_field($field_name, 'form', $entity_type, $entity, $form, $form_state, $options);
}

Sitenizde araçların etkin olması gerektiğini unutmayın. Drupal'ın varsayılan olarak böyle bir yardımcı işlev içermemesi çok kötü.


2

Ctools yöntemini çalıştıramadım ve bunun yerine bu şekilde yapmaya karar verdim.

Bu kod bir form işlevinin içinde olur, bu yüzden $ form ve $ form_state zaten iletilirdi.

function form_function($form, &$form_state) {

Önce, oluşturmak istediğiniz alana sahip bir türden boş bir düğüm oluşturun.

    $entity = new stdClass();
    $entity->title = "Temp Object";
    $entity->type = "node_type";
    node_object_prepare($entity);

Form değişkenlerini çoğalttım, böylece orijinali gizlemeyecektim.

    $temp_form       = $form;
    $temp_form_state = $form_state;
    field_attach_form("node", $entity, $temp_form, $temp_form_state);

Aradığınız alanı dışarı çekin ve forma ekleyin.

    $form["field"] = $temp_form["existing_field"];
}

Bu yöntemi, taksonomi seçme widget'ını, taksonomi onay kutuları widget'ını ve özel bir formdaki Hiyerarşik Seçim widget'ını oluşturmak için kullandım. (Taksonomi Otomatik Tamamlama gereci oluşturuyor, ancak gönderim sırasında hata veriyor)

Sonunda render ve yazdır

drupal_render(drupal_get_form("form_function"))

Bu, bir alan widget'ını özel bir formda kullanmanın kolay bir yolu gibi görünüyor. Yine de mevcut bir Bundle'a bağlı. Benim durumumda, alanları gerektiği gibi oluşturup yapılandırdığım yapay bir İçerik Türü kullanıyorum. Bu biraz sahte ama diğer yöntemler için de gerekli. Sadece not etmek: ctools_field_invoke_field()Yukarıda açıklanan yöntem de çalışır.
Bernhard Fürst

0

Kullanarak bireysel alanlardan formlar oluşturdum

field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $form, $form_state);

Bu, herhangi bir biçimde kullanılabilecek gerekli widget formunu döndürmelidir.

 $custom_form['form_element_to_display'] = field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $custom_form, $custom_form_state);

Yukarıdaki 2 parametrenin değerlerini almak için:

$field = field_info_field($field_name);
$field_instance = field_info_instance('node', $field_name, $node_type);

Diğer parametreler için api bağlantısını buradan kontrol edebilirsiniz.

Bu, içerik türleri alanında tanımlanan varsayılan widget formunu döndürür.

Umarım bu birine yardımcı olur :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.