hook_theme() affects display order of a node - drupal

I have a node with many CCK fields. I want to hide a field from anonymous user. I found there are roughly two approaches from http://www.lullabot.com/articles/modifying-forms-5-and-6. First, I tried theme_theme() with the code below
function ssaa_theme1(&$existing, $type, $theme, $path) {
return array(
'volunteer_node_form' => array(
'arguments' => array('form' => null),
),
);
}
function ssaa_volunteer_node_form($form) {
$out = '';
if (user_is_anonymous()) {
unset($form['field_active']);
}
$out .= drupal_render($form);
return $out;
}
This simple code worked well as I expected but produced strange result too. Save/Preview buttons are appeared on the top of the form and I couldn't move them to the bottom. At first I suspected drupal_render() function but it didn't do anything about the order. It produced same result when ssaa_volunteer_node_form() function was empty.
So I tried second option which uses hook_form_alter() and succeeded. But I still want to figure out why first approach didn't work properly. I think it's more easy and light way to do what I want to do.
Any ideas?

If you only want to deny this one field to users, it makes sense to form_alter it. Otherwise, I also suggest you use Content Permissions. It will give you the power to toggle such settings for all your fields without needing a text editor.
CCK Field input forms do not accept hook_form_alter() very well. They are inserted into the node edit form late in the cycle, so to speak.
This example demonstrates how disable CCK form elements, it can be adapted to suit your needs.
As you have a very specific need, you might want to look at the new Field Permissions module. It is still in development (and I have not tried it), but it allows you to opt-in individual fields to Content Permissions. This prevents your Permissions screen from getting cluttered and from all new fields defaulting to inaccessible.

I think you can just use the Content Permissions module that comes bundled with CCK to set field-level permissions. Once you enable that module, all of your fields will appear in the Permissions area and you can deny permission to anonymous users there. I think that would be a much easier way to accomplish this.

I ran into the same problem in Drupal 6 recently, and your question is valid.
When I displayed the $form object (from template.php) using Devel's dsm() function, I found that the buttons were somehow showing a weight of 0.0111, a float.
The hook_theme() and then hook_form() in template.php seem to be behaving wrong.
Using hook_form I made no changes to the $form object, and returning drupal_render($form) the Save/Preview buttons were at the top.
To anyone that needs to use these hooks, you must ALSO create a form_alter where you set the weight of the buttons. This counteracts the bug and gets your buttons to the bottom again.
$form['buttons']['#weight'] = 100;
Note: I could not set the weight in my hook_form() code, it had to be in a form_alter

Related

SilverStripe field-level Page editing permissions

I need to implement field-level permissions in a Page model, in a SilverStripe 3.2 website.
Let's imagine I have an ArticlePage.php model. It has the usual fields like $MenuTitle and $Content, and I've added other properties like $Subtitle and $Author.
I can protect the whole model by using providePermissions() and the associated canEdit() methods, but I need to protect individual fields / page properties.
What I need to do is:
Admins should be able to edit all fields
Users in another permissions group should only be able to edit and save $Subtitle
Is this possible in SilverStripe 3.2? Is there a SilverStripe way of doing it?
If not, is there a way I can Identify the user group of the current user and then perhaps conditionally show the $field->addFieldToTab() code? Is it possible to stop the user saving a field by posting the data maliciously, perhaps by adding the missing fields via inspector?
Thanks in advance.
So here's my own answer. This post was helpful: https://www.silverstripe.org/community/forums/customising-the-cms/show/11693
You can conditionally show CMS fields and tabs using code like the post demonstrates:
public function getCMSFields()
if(!Permission::check('PERMISSION_LABEL'){
$fields->removeFieldFromTab("Root.Main","MenuTitle");
$fields->removeByName('BannerImages');
// etc...
}
// etc...
}
Having defined the permission:
public function providePermissions()
{
return array(
'PERMISSION_LABEL' => 'Can edit some fields',
);
}
My concern with this approach was that a user could still create a form field on the page using inspector or JS and submit values for fields they should not be able to see.
Having tested this it appears that field values are not saved if they are not listed on the page, but are sent with the POST data. Although I'd love to know if a SilverStripe expert could confirm that.

Drupal: Taxonomy: Make vocabulary optional for a specific content-type

I understand that I need to go down the path of hook_form_alter, however this doesn't appear to be getting me very far, initially:
hook_form_alter(&$form, &$form_state){
drupal_set_message($form['form_id']['#value']);
switch ($form['form_id']['#value']){
case 'partner_node_form':
$form['taxonomy'][1]['#required']=FALSE;
break;
}
}
DSM outputs partner_node_form and the code fires when I go to /node/add/partner, however it doesn't make the field optional, and it is still given a red asterisk.
If I submit the form, it fails, stating that the field is required, but now DSM outputs admin_block_theme_form instead, which is preventing my alter code from even running.
Obviously, I'm quite lost, please help!
I knew that there was a solution to this ;). Found it today when I was working on something else.
Install content_taxonomy module. Once you do this you will have taxonomy as a CCK field in all the content types. Hence you can make it optional for a selected content type. You have an option to select the vocabulary and moreover you can use this like any other CCK field.
define('MY_VOCABULARY', 1);
$form['taxonomy'][MY_VOCABULARY]['#required'] = 0;
it's works fine in drupal 6. what drupal version you use ?

Show secondary links in views only

I'm building a site in Drupal and I only want to show the secondary links on the
pages that use the Views I've created. I tried using the $secondary_links variable
in the views-view.tpl.php but the variable is null. How can I achieve this?
The secondary links are as mac correctly writes only available in page.tpl.php, but if I understand you correctly, the best solution is not getting the secondary links into your view.
With your theme, the secondary links, will most likely be printed out where they should, regardless of what is being displayed, be it your views, nodes, the front page etc. Views are displayed and everything else you render, is wrapped in the page template, that controls where menus are located, regions and other fun stuff.
Now, if you don't want to alter this, the location of the menus, their styling and this stuff, you shouldn't be printing the secondary menu in your views template, you shouldn't be doing anything with it at all.
The solution is simple
It's using something that mac mentioned but in a different way: preprocess function. These functions are used to in your template.php file, to add some logic to your variables. You can alter variables or remove them altogether. What I would do, would simply be to remove the primary links, by setting the value of $primary_links to an empty text string.
This would effectively remove the primary links, so only the secondary links are displayed. You could also display the secondary links as the primary, but this might cause confusing to your users. You just need to add some logic to control when this should happen and you are set.
Have you activated the secondary links from the theme settings? That would be:
http://example.com/admin/build/themes/settings/name_of_your_theme
I believe once you have activated the option, the variable will be populated.
EDIT: Thinking a second more, I would also comment that I am not sure if the primary and secondary links are passed to the views templates. I believe those are passed to the page.tpl.php file instead. If I am right, and for some reason you want to add that variable to those passed to the views template, you will have to use a preprocess function, like explained here.
EDIT #2: Indeed if you only need the secondary menu used in a specific views template, another approach would be to simply call menu_secondary_links() from within the template. This is not the most elegant solution ever, as it puts in a theming element something that should belong somewhere else, but it's up to you to make the call whether that menu in the views is a core functionality or a styling element.
HTH!
You can use the following code to show secondary menu on any view
function YourTheme_preprocess_views_view(&$vars)
{
$menu_sec = menu_navigation_links('menu-secondary');
$vars['custom_menu'] = theme('links__menu-secondary', array('links' => $menu_sec));
}
or you can even use other preprocess function depending upon your needs.
Further you can call it on .tpl.php file using:
<?php
$menu_sec = menu_navigation_links('menu-secondary');
print theme('links__menu-secondary',
array(
'links' => $menu_sec,
'attributes'=>array(
'class' => array('nav', 'nav-pills', 'p-f-subfilter'),
)
)
);
?>

Change size of user/password login box

I don't know how to change the size of the login username/password boxes on the drupal site that I'm trying to build. I'm stumbling through the theming, and don't know where to find the file that needs to be changed in order to have boxes that fits the aesthetic (so a file path would be very helpful).
I'm hoping it's a css solution. You can see the site first hand at innovatefortomorrow[dot]org and my firebug screenshot http://www.jonrwilson.com/user-login-form.png (I don't have enough reputation points to attach an image or two hyperlinks).
Thanks!
read this as well! This is an alternative answer!
Ok... you are about to enter one of the most exciting and complex features of Drupal: the form API or - for brevity - FAPI. Some theory first, and then the solution! :)
All forms in Drupal are built by the drupal_get_form() function, that accepts an array as parameter. Each field in the array is basically a field of your form, and each field has a number of proprieties, each of them define additional characteristics of the the field, like for example its default value, if it is required or optional and - yes - in the case of textfields... how large they have to be! You can find a detailed explanation of the structure of form arrays here on the drupal site.
The beauty of the form API is that the function that renders the form invokes a number of hooks at various moments during its building process, so you can implement these hooks in order to "alter" a form before it is finalised and sent to the browser.
The most commonly hooks for form alteration are hook_form_alter() and hook_form_FORM_ID_alter(). The first is executed for any form processed by the drupal engine, the latter only for the specific form named "FORM_ID". I will not get into any more details on the internal working of the form API, but here you can read more.
As for your specific case, I assume you are using the standard "user block" shipping with Drupal. In this case I suggest you implement hook_form_FORM_ID_alter() in a form similar to this one:
mymodule_form_user_login_block_alter(&$form, $form_state) {
$form['pass']['#size'] = 43;
}
Hope this helps! :)
I think in this case you have to go to the your html ( or tpl), not your css file to edit it.
One quick way is to search the relevant string (i.e., size="43" name="name" etc) in order to find the correct part.
Here is the way to theme a user login form in drupal 6 with the preprocess function in a template file and not in a module.
in template.php put this code:
function yourThemename_preprocess_user_login(&$variables) {
$variables['form']['name']['#size'] = 15;
$variables['form']['pass']['#size'] = 15;
$variables['rendered'] = drupal_render($variables['form']);
}
create a new file user-login.tpl.php (if it's not already there) and just paste this:
<?php print $rendered; // this variable is defined in the preprocess function user_login and print the login form ?>
Don't forget to clear theme cache or system cache in the performance settings.

best way to give editors ability to assign background images in drupal 6

I've got a design in drupal that calls for a different background image on different pages. I'd like to make it easy for the site editors to assign the image. My first thought was adding a cck field to the Page type where they could assign the image. That will work nicely for node pages, but won't work for views pages. I guess instead of creating the views pages directly, I could wrap them in nodes.
My other idea is to create a BGImage cck type, and then some kind of matrix page where they can assign a given BGImage node to a content node or view, but that sounds complex.
Any better ideas out there? (In a way, this is akin to controlling block visibility, I suppose.)
After creating a content type to use as a repository for background images, I think that it would be a fairly quick module to give you a block with dropdown box to choose from uploaded images.
Look up hook_block for the only hook you'll need.
if $op == view
pseudocode follows (but it should be clear enough to go on)
$res = db_query('select field_my_image_fid FROM {mycontenttype}');
while ($img = db_fetch_obj($res) {
$my_content .= $img->whatever
return array(
'subject' => '<none>',
'content' => $my_content
)
I would indeed suggest to wrap them into nodes, the Views Attach Module might help here.

Resources