Treat the node nids as a field (for display only in a content type) in drupal 7 - drupal

I need to use the nid of a node as field in a content type: i need to choose where to print it (put it before some fields but after others) and format it as i wish. the only thing i could think about is create a "fake" custom field with no widget to insert it buth with a theme formatter to display it but it seems to me that this is a little to complicated. How should i do it?

If I understand correctly, you just want to expose data to the node view. Could it be as easy as using hook_node_view() from a module?
With that, you can set a 'fake' field to be sent out to the content array of the node, which you can access in the node template.
From drupal.org:
<?php
function hook_node_view($node, $view_mode, $langcode) {
$node->content['my_additional_field'] = array(
'#markup' => $additional_field,
'#weight' => 10,
'#theme' => 'mymodule_my_additional_field',
);
}
?>

Related

Changing Type from Content To Global or VDC Drupal

I'm using Drupal 7 with the view_database_connector module. I'm currently working with a view that consists of a table displaying database information. My goal is to have a field with action buttons corresponding to each row, such as delete.
I am not allowed to use global php as a field.
I've attempted to make a custom module following this. I can currently use this module on content tables, however, when I try to use it on my view_database_connector table, I'm unable to add it as a field, since it's not apart of the same group.
Here's where I set up the information for making the action:
function mymodule_views_data_alter(&$data) {
// debug($data['node']);
$data['node']['actions'] = array(
'title' => t('Actions'),
'help' => t('Clickable links to actions a user may perform on a Node.'),
'field' => array(
'handler' => 'mymodule_views_handler_field_actions',
'group' => 'Content',
'click sortable' => FALSE,
),
);
}
I've tried deleting Content, changing it to global, and changing it to the VDC type, but none of that changes it into Global or VDC.
Alternatively, if there's an easier way just to hook into a field that has a button to run my code which will download a file, that could circumvent this issue.
You don't have to create this feature on your own - it already exists in views. There is a field type with actions as delete.
Other option is to use option called "rewrite value of this field" (or similar). With it you can make your field from views interface, and totally rewrite it's output. You can use token and some of them for sure contains node id, so you can use it to generate link to node deleting/editing/viewing pages.

Silverstripe tumblr-like Post Types

I am trying to create a back-end interface for silverstripe that gives the CMS user the option to choose between a set of Post Types (like tumblr) in Silverstripe3. So they can choose to create a News Post, Video Post, Gallery Post, etc.
I initially started off giving all Posts the necessary fields for each Type and adding an enum field that allowed the user to choose the Post Type. I then used the forTemplate method to set the template dependent upon which Post Type was chosen.
class Post extends DataObject {
static $db = array(
'Title' => 'Varchar(255),
'Entry' => 'HTMLText',
'Type' => 'enum('Video, Photo, Gallery, Music')
);
static $many_many = array(
'Videos' => 'SiteVideo',
'Photos' => 'SitePhoto,
'Songs' => 'SiteMp3'
);
public function forTemplate() {
switch ($this->Type) {
case 'Video':
return $this->renderWith('VideoPost');
break;
case 'Photo':
return $this->renderWith('ImagePost');
break;
etc...
}
function getCMSFields($params=null) {
$fields = parent::getCMSFields($params);
...
$videosField = new GridField(
'Videos',
'Videos',
$this->Videos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
$photosField = new GridField(
'Photos',
'Photos',
$this->Photos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
return $fields;
}
}
I would rather the user be able to choose the Post Type in the backend and only the appropriate tabs show up. So if you choose Video, only the Video GridField tab would show up. If you choose Photo Type only the Photo's GridField would show.Then I would like to be able to call something like
public function PostList() {
Posts::get()
}
and be able to output all PostTypes sorted by date.
Does anyone know how this might be accomplished? Thanks.
Well the first part can be accomplished using javascript. Check out this tutorial and the docs let me know if you have questions on it.
The second part would be trickier but I think you could do something with the page controller. Include a method that outputs a different template based on the enum value but you would have to set links somewhere.
I managed this with DataObjectManager in 2.4.7 as I had numerous DataObjects and all were included in one page but I'm not sure if that is feasible in SS3.
return $this->renderWith(array('CustomTemplate'));
This line of code will output the page using a different template. You need to include it in a method and then call that method when the appropriate link is clicked.

hook_nodeapi() - How to order additional fields

I used hook_nodeapi to add my custom field to a type of node
$node->content['my_new_field'] = array(
'#value' => $content,
);
However the new field is only appeared at the end of the content. Is there anyway for me to select a place for it to display ? e.g: between Title and Body.
For some reason I won't be able to use CCK, I want to do it programmatically.
Thanks in advance
There is something called weight. If you llok at the code from API docs, you'll see how that is supposed to work. Lower numbers appear before higher numbers.
So you could do something like
$node->content['my_new_field'] = array(
'#value' => $content,
'#weight' => 5, //play with the values until you are happy with the output
);
Couldn't you implement hook_load instead to append the node object with your custom fields:
http://api.drupal.org/api/function/hook_load/6
Then you could theme it however you want in node-customtype.tpl.php. Just a thought.

Drupal pass argument to page

I have a custom Drupal module displaying some data in a table. Each row has a link which if clicked will delete the relevant row. Specifically, when the link is clicked it will take the user to a confirmation page. This page is really just a drupal form which says 'are you sure' with two buttons: 'Yes', 'No'. I figure I will need to pass the rowID to the confirmation page.
My question: What is the typically way to pass data to a new page in Drupal 7? I guess I could just add the rowID to the URL and use the $_GET[] from the confirmation page... I don't think this is very safe and was wondering if there was a better 'Drupal' way.
Thanks!
You'd use something like the following
<?php
function yourmod_menu() {
// for examlple
$items['yourmod/foo/%/delete'] = array(
'title' => 'Delete a foo',
'page callback' => 'drupal_get_form',
'page arguments' => array('youmode_foo_delete_confirm', 2), // 2 is the position of foo_id
'access arguments' => array('delete foo rows'),
'type' => MENU_CALLBACK,
);
return $items;
}
function yourmod_foo_delete_confirm($form, &$form_state, $foo_id) {
// load the row
$foo = yourmod_get_foo($foo_id);
// build your form, if you need to add anything to the confirm form
// ....
// Then use drupal's confirm form
return confirm_form($form,
t('Are you sure you want to delete the foo %title?',
array('%title' => $foo->title)),
'path/to/redirect',
t('Some description.'),
t('Delete'),
t('Cancel'));
}
?>
You can look here for examples of how core modules do it (have look at node_delete_confirm)
The simplest solution would be to use an existing module created for this purpose:
http://drupal.org/project/entityreference_prepopulate (for entity references)
http://drupal.org/project/nodereference_url (for node references)
http://drupal.org/project/prepopulate (for other form values)
You can configure which form values can be set from the URL, then rewrite the fields displayed in your table to generate the necessary links.
If the data are nodes, you can make the link node/%/delete where % is the nid. Drupal knows how to handle the delete page, as its a core path. Then, the delete confirmation follows the rest of the system and is very 'Drupal'.
I am not sure if this changed at all in Drupal 7, but this is what I did for countless modules.

Drupal form with custom ID

Correct me if I'm wrong, after reading drupal fapi related articles, I got the impression that fapi generates 'id' attributes by itself. It allows developers to assign 'name' attribute only. If that's the case, is there a way I can set desire 'id' value for elements? Because, I want my elements to have meaningful 'id' so that html/jquery code would be easier to read as well as save my time from going through already written jquery code to change those all 'id's that I've used inside.
P.S:drupal version - 6.x
Ok found the solution. I can use the #attributes key of the $form element to set any additional attributes (such as class, id, etc.). Thanks for your help so far.
I had a similar issue to deal with. I needed to have multiple forms on the same page so I had to change the ids of the form and its elements to prevent duplicate ids. I did something like the following:
function voci_comment_form($form, &$form_state, $cid) {
$form['#attributes']['id'] = 'voci-comment-form-' . $cid;
$form['#attributes']['class'][] = 'voci-comment-form';
$form['body'] = array(
'#title' => 'Post a comment',
'#type' => 'textarea',
'#resizable' => FALSE,
'#rows' => 1,
);
$form['comment'] = array(
'#type' => 'submit',
'#value' => 'Comment',
);
foreach ($form as $k => &$element) {
$k = str_replace('_', '-', $k);
$element['#attributes']['id'] = "edit-$k-$cid";
$element['#attributes']['class'][] = "edit-$k";
}
return $form;
}
This basically sets unique ids based on the $cid that is passed in. The code also adds classes to each element in the form so you can style it easily. I'm sure a more robust solution is possible but this is the basic idea. Tested in Drupal 7.
It's true that you can set $element['#attributes']['id'] and that will apply to the form field. However, it will break labels and #states in Drupal 7 because the rest of the rendering pipeline reads the ID from somewhere else. So for your labels and #states to keep working, use set the ID to $element['#id'] instead (an undocumented property that nonetheless is how the form API watches ID internally).
Make sure to pass your ID through drupal_html_id as well to ensure no conflicts.
This problem doesn't really have much to do with the Drupal-FAPI itself, but more with how Drupal theme forms (create the markup).
If you want to alter all forms on your site, you can overwrite the theming functions that is used for forms and the different type of form fields.
If you just want to overwrite some forms or form fields, you can set the #theme attribute on the form or an element, to change which function should be used for creating the markup.

Resources