Suggesting different templates when theming a node form - drupal

function posts_theme($existing, $type, $theme, $path) {
return array(
'post_node_form' => array(
'arguments' => array('form' => NULL),
'template' => VARIABLE,
)
);
}
This is the way of suggesting a template to render the 'post_node_form' in Drupal 6. BUT I want to get the node editing form from 2 different paths:
via AJAX through drupal_get_form('post_node_form')
via default node/add/post
If I replace "VARIABLE" depending on the path (or whatever other condition), it will not work because it seems? the name of the template is cached and you need to flush caches to refresh it.
Any solution of suggesting different form templates?
NOTE. This is not the case of node template, (then you can put the template suggestions in the preprocess hooks). It's about node FORM.

Add this function/or modify if exists into template.php of your theme:
function phptemplate_preprocess_page(&$vars) {
// ...
$node = menu_get_object();
if ($node->type == 'post') {
$vars['template_files'][] = VARIABLE;
}
// ...
}

Ok, I answer my own question:
The key of the solution is the hook preprocess_NAME_OF_MY_FORM , that is executed every page load and can be in your module or your theme.
So in my case, I wrote in my "posts" module:
/**
* Implementation of hook_theme().
*/
function posts_theme($existing, $type, $theme, $path) {
return array(
'post_node_form' => array(
'arguments' => array('form' => NULL),
'template' => 'post-form-custom',
)
);
}
function posts_preprocess_post_node_form(&$vars) {
// I check the path to know if node_form is retrieve through normal way or ajax way.
if (check_plain(arg(0)) == 'node'){
$vars['template_files'][] = 'post-form-default';
}
}
I had in my module folder the files post-form-custom.tpl.php and post-form-default.tpl.php

Related

Adding elements to a field widget in Drupal 8

What I need to accomplish is adding a link to a node to field widgets (the node contains the formatted instructions to properly compile the field).
So far I've been able to add the node reference field in the field config form, using Third Party Settings:
function mymodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
if ($form_id === 'field_config_edit_form' && $form_state->getFormObject()->getEntity()->get('entity_type') == 'myentity') {
$field = $form_state->getFormObject()->getEntity();
$help_page_id = $field->getThirdPartySetting('mymodule', 'help_page_id');
$form['help_page_id'] = array(
'#type' => 'entity_autocomplete',
'#title' => t('Help page'),
'#target_type' => 'node',
'#selection_handler' => 'default',
'#selection_settings' => array(
'target_bundles' => array('help_page'),
),
'#default_value' => $help_page_id ? Node::load($help_page_id) : NULL,
'#weight' => 100,
);
$form['#entity_builders'][] = 'mymodule_form_field_config_edit_form_builder';
}
}
Now I'm having troubles retrieving this information when showing the form, and altering the field widget in order to display the link.
Using hook_field_widget_form_alter, I cannot get the custom configuration value from the arguments I have:
function mymodule_field_widget_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) {
}
I guess I have to load the field configuration entity, but I don't know how.
I didn't test it, but something like this should work:
function mymodule_field_widget_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) {
// Add a suffix to widget form elements for all fields of type entity_reference.
$field_definition = $context['items']->getFieldDefinition();
if ($field_definition->getType() == 'entity_reference') {
// TODO: Render the node link to $link
$element['#suffix'] = $link;
}
}

Drupal7 | Custom Module | How to Display Template?

I'm having trouble figuring out how to display a template that lives inside of my custom module.
This is what I have:
<?php
function brl_footer_theme($existing, $type, $theme, $path) {
$theme = array();
$theme['brl_footer'] = array(
'render element' => 'content',
'template' => 'brl-footer',
'path' => drupal_get_path('module', 'brl_footer'),
);
return $theme;
}
/**
* Implements hook_block_info().
*/
function brl_footer_block_info() {
$blocks = array();
$blocks['brl_footer'] = array(
'info' => t('Custom Footer'),
);
return $blocks;
}
I have a template file in the module called brl-footer.tpl.php
It contains very basic HTML:
<h1>here's some content</h1>
Is it possible to display my template through the custom block 'brl_footer' that's being created?
The custom block is active and has been assigned to the proper region.
Any help on this would be hugely appreciated -
You'll need to implement hook_block_view to define what gets displayed in your block.
Also, if your template is just static content, you don't need to specify a "render element" or "variables" for your theme hook (though you could still make variables in a preprocess function).

Using Drupal's node form in a new page

In a custom module I want to have a page defined in hook_menu, that shows the add form for a specific content type, with some modifications to the form.
So far it's working, and even saving the new node, but only with the default values I'm setting in the code, i.e. it's not picking up anything the user types into the form. I checked and $form_state['input'] contains the inputted values, but $form_state['values'] doesn't, so the new node gets saved wrong.
Here's the relevant code:
function mymodule_menu() {
return array(
'admin/content/myadd/%' => array(
'title' => 'my custom add page',
'page callback' => 'mymodule_node_add',
'page arguments' => array(3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
),
);
}
function mymodule_node_add() {
module_load_include('inc', 'node', 'node.pages');
//I'm doing a print here instead of returning because I'm calling this page
//in an AJAX popup, so I don't want the whole page to output, only the form.
print render(drupal_get_form('mymodule_node_add_form'));
}
function mymodule_node_add_form($form, &$form_state) {
if (!isset($form_state['node']) {
global $user;
$node = (object) array(
'uid' => $user->uid,
'type' => 'mycontenttype',
'language' => LANGUAGE_NONE,
);
//this is setting a default value
$node->myfield = array(LANGUAGE_NONE => array(array('value' => arg(3))));
$form_state['build_info']['args'] = array($node);
$form = drupal_build_form('mycontenttype_node_form', $form_state);
$form['actions']['submit']['#submit'][0] = 'mymodule_node_add_form_submit';
//there's a lot more customization of the form here, like adding fields, etc.
}
return $form;
}
function mymodule_node_add_form_submit($form, &$form_state) {
//here's where $form_state['input'] is correct but $form_state['values'] isn't.
$node = node_form_submit_build_node($form, $form_state);
node_save($node);
$form_state['values']['nid'] = $node->nid;
$form_state['nid'] = $node->nid;
$form_state['redirect'] = 'some/other/page';
}
So, am I doing something wrong here? Should I be concerned about form ids being wrong? (my form's id is mymodule_node_add_form, but the actual form might output mycontenttype_node_form), would this affect me?
You want hook_form_alter() (see api.drupal.org). I would try to use the existing content type's form and simply alter it with hook_form_alter(). I would also try to first get it working as a standard, non-AJAX page, so you can get all the advantages of dpm() and other debugging techniques. When you have it down solid, then modify it to take advantage of the AJAX techniques.
mymodule_form_alter(&$form, &$form_state, $form_id) {
// use this with your devel module turned on to verify
// your $form_id and contents of all forms that load on a given page
dpm($form);
// once you verify your $form_id, you can begin accessing your form and altering it
switch( $form_id ) {
case 'my_target_form_id' :
// this part is just pseudocode, I haven't memorized the $form structure,
// you can get it from your dpm().
if( $form['node']->type == 'my_target_content_type' ) {
$form['actions']['submit']['#submit'][0] = 'mymodule_node_add_form_submit';
}
break;
}
}

Drupal add an action on the content listing

Is it possible to add an action on the /admin/content page. We got "publish selected content" or "delete selected content" etc etc...
http://screencast.com/t/v2ZMedCqy3g
I'm trying to add an action here from a module installation.
Thanks
You need to implement hook_node_operations(). You can look at the pathauto_node_operations() as example.
function pathauto_node_operations() {
$operations['pathauto_update_alias'] = array(
'label' => t('Update URL alias'),
'callback' => 'pathauto_node_update_alias_multiple',
'callback arguments' => array('bulkupdate', array('message' => TRUE)),
);
return $operations;
}
Notices that the callback specified takes an array of node ids, plus the additional callback arguments as you specified in your hook implementation (see above example).
// The call back specified above ^
function pathauto_node_update_alias_multiple(array $nids, $op, array $options = array()) {
$options += array('message' => FALSE);
$nodes = node_load_multiple($nids);
foreach ($nodes as $node) {
pathauto_node_update_alias($node, $op, $options);
}
if (!empty($options['message'])) {
drupal_set_message(format_plural(count($nids), 'Updated URL alias for 1 node.', 'Updated URL aliases for #count nodes.'));
}
}

Theming Module Output

What I am trying to do is generate some raw output within a module.
I would like to pass an array of data through to a template file, and then use that data to populate the code from the template. The template is represented by a file in my theme folder.
I have a hook set up for a certain URL (/itunes):
$items['itunes'] = array(
'page callback' => 'itunespromo_buildpage',
'type' => MENU_SUGGESTED_ITEM,
'access arguments' => array('access content'),
);
..inside itunespromo_buildpage...
function itunespromo_buildpage() {
//grab some data to pass through to template file, put into $promo_data
$details = theme('itunes_page', array(
'promo_data' => $promo_data,
));
return $details;
}
Here is the hook_theme():
function itunespromo_theme() {
return array(
'itunes_page' => array(
'template' => 'itunes_page',
),
);
}
Inside my theme's template.php:
function geddystyle_itunes_page($vars) {
return print_r($vars['promo_data'], true);
}
Right now, $promo_data is being passed through fine, and it is print_r'd on to the result page. However, I'd like to then take this $promo_data variable and use it in my itunes_page.tpl.php template file.
I'm kind of certain I'm close here. Am I supposed to call some sort of render function and pass the $promo_data variable to it from function itunespromo_theme()?
I believe you just need to update your hook_theme() to provide the ability to send variables to your template file.
Something like this should do the trick:
function itunespromo_theme($existing, $type, $theme, $path) {
return array(
'itunes_page' => array(
'variables' => array(
'promo_data' => NULL,
),
'template' => 'itunes_page',
)
);
}
Also, instead of calling the theme() function directly what you want to be doing is actually constructing a renderable array and letting Drupal call the theme() function. What you should be doing is calling drupal_render which in turn calls theme() for you. Look at this piece of advice here for a little more clarity:
http://drupal.org/node/1351674#comment-5288046
In your case you would change your function itunespromo_buildpage to look something like this:
function itunespromo_buildpage() {
//grab some data to pass through to template file, put into $promo_data
$output = array(
'#theme' => 'itunes_page',
'#promo_data' => $promo_data //call $promo_data from the tpl.php page to access the variable
);
$details = drupal_render($output);
return $details;
}

Resources