Drupal 7 preprocess_views not working - drupal

I have the following code in my Drupal 7 template.php file:
function mytheme_preprocess_views_view__videos__videos(&$vars) {
drupal_add_css(drupal_get_path('theme', 'mytheme') . "/css/qwembed-jquery-1.0.css");
drupal_add_js(drupal_get_path('theme', 'mytheme').'/js/jquery.swfobject.1-1-1.min.js', array('type' => 'file', 'scope' => 'footer'));
drupal_add_js(drupal_get_path('theme', 'mytheme').'/js/qwembed-jquery-1.0.js', array('type' => 'file', 'scope' => 'footer'));
}
I need to load these css and js file only when this view is displayed.
the view display name is: Videos
the view Machine Name is: videos
and the override files are:
views-view--videos--videos.tpl.php
views-view-unformatted--videos--videos.tpl.php
views-view-fields--videos--videos.tpl.php
any ideas why this is not working?

The problem is likely that you try to implement a preprocess function based on the same naming pattern as used for template overrides. But preprocess functions are a bit different in that by default, they can only be implemented based on the name of the 'base' template, and do not have the same mechanism for 'specific' versions based on template suggestions. See my answer to a more generic question for details.
So you'd need to fall back to implementing the 'base' preprocess function, and check if it gets called for the desired view (and optionally display) within that function, roughly like so:
function [yourThemeName]_preprocess_views_view(&$vars) {
$view = $vars['view'];
if ('videos' == $view->name) {
// Add desired manipulations for all 'videos' views
if ('videos' == $view->current_display) {
// Add desired manipulations for the 'videos' display only
}
}
}
You could also add the behavior you expected by implementing a generic preprocess function that tries to call specific versions by checking for functions with the proper name - see the end of this article for an example - but this introduces quite some processing overhead and would only make sense, if you need specific preprocess functions for many views.
There are more 'base' preprocess functions per view type that you can implement directly - see the list of template_preprocess_views_view_* in 'views/theme/theme.inc' for the available options.
As a base rule, whenever there is a template_preprocess_* function for a template, you can implement a corresponding yourThemeOrModuleName_preprocess_* function as well. If you need to manipulate for templates based on template name suggestions, you need to find the 'base' preprocess function name, implement that and check for your specific case in that function (like for the specific view as in the example above).

Related

Silverstripe 4 use additional custom HTMLEditorField

In Silverstripe 4 how can we use different HTMLEditor configs ?
I'd like to have two different HTMLEditorFields in the same environment.
One with all functionality and all Buttons.
And another one (MyCustomHTMLEditorField) with reduced functionality and e.g. only 3 buttons (underline, italic, bold).
How do you use ::set_active ?
How to extend HTMLEditorConfig ?
Yes, i've read the documentation but How can this be archived?
There can be multiple configs, which should always be created / accessed using HtmlEditorConfig::get(). You can then set the currently active config using set_active().
Can you provide an Example?
Any help welcome.
The documentation at https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield/ goes to length about how to define and use HTMLEditorConfig sets.
HTMLEditorConfig::set_active() is really for if you're intending to set an editor for use in multiple HTMLEditorFields in a given form or admin section, or to override the config for all admin sections. It more-or-less sets the 'default' config. That won't be so useful in your case, as it sounds like you want to set a configuration for a given HTMLEditorField.
Setting configuration
This is detailed in the documentation at https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield/#adding-and-removing-capabilities
Usually this is done in your _config.php (or in some separate class which then gets called from _config.php - unless you only need it in a very specific section, in which case you could set this up or call your special class from that admin's init() method).
The examples in the documentation here modify the default ('cms') config. This is useful if you want to modify the configuration that is used by default. So do this for your config that you've referred to as having "all functionality and all Buttons".
Setting up a new HTMLEditorConfig
Calling HTMLEditorConfig::get($configName) will get the existing config based on the name you pass it - but if there is no existing config, it will create a new one. So you could call $customConfig = HTMLEditorConfig::get('some-custom-config') - now your $customConfig variable holds a new configuration that you can configure however you so choose (insert buttons, enable plugins, define whitelisted elements, etc).
Using configuration
This is discussed in the documentation here: https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield/#specify-which-configuration-to-use
I've already mentioned the set_active() - if you're going to set up multiple HTMLEditorFields in a form for example you can use that in your getCMSFields() method:
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', HMLEditorField::create('Content')); // This will use the default 'cms' config.
HTMLEditorConfig::set_active('some-custom-config');
$fields->addFieldToTab('Root.Main', HMLEditorField::create('OtherContent')); // This will use the 'some-custom-config' config that you defined.
// Don't forget to reset to the default.
HTMLEditorConfig::set_active('cms');
return $fields;
}
You can also, as explained in the docs, set your config by name for a given HTMLEditorField which is preferred if you're using a non-default for one one field.
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', HMLEditorField::create('Content')); // This will use the default 'cms' config.
$fields->addFieldToTab('Root.Main', HMLEditorField::create('OtherContent')->setEditorConfig('some-custom-config')); // This will use the 'some-custom-config' config that you defined.
return $fields;
}
Note that the syntax I used here is slightly different to the docs - this allows you to avoid passing in the second and third constructor arguments that you're not changing from the defaults. Keeps things a little tidier.
Disclaimer: All of the code above was written from memory, so it may need some tweaks to work correctly.

how to modify function of contributed module in drupal?

I have the reqirement to modify simplenews_build_newsletter_mail() function in simplenews module but, we don't modify directly contributed module function.
can someone gives me ways to modify simplenews_build_newsletter_mail() function ?
Most of the data moving around in drupal can be altered through 'hooks'
the function you want to alter simplenews_build_newsletter_mail(&$message, SimplenewsSourceInterface $source) is being called from simplenews_mail($key, &$message, $params) which is simplenews implementation for hook_mail
fortunately all the output for hook_mail can be altered though hook_mail_alter().
What you need to do is to create your own module, then implement hook_mail_alter() in your new custom module. find your target emails, change them.
you will need to identify which mail you would like to alter using the mail $id, The id will be {$module}_{$key} where the module is the drupal module generated this email (simplenews) in your case.
find more information here https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_mail_alter/7
/**
* Implements hook_mail_alter().
*/
function mymodule_mail_alter(&$message) {
switch ($message['id']) {
case 'simplenews_node':
case 'simplenews_test':
// Do your magic.
break;
}
}

Buddypress plugin Group Hierarchy

Buddypress has a group functionality in which I combined with the plugin BP Group Hierarchy so that I can create an hierarchy of groups based on user role.
However, the plugin used an method as taught by Buddpress in group-extension-api> link.
The group steps are registered using the function bp_register_group_extension and add_action are called. I tried to remove the action by with no success. Because I not really understand how the array works i.e. array( &$extension, \'_register\' ), so I go search out and found this post.
There's a line stating that
The new format for the above object referenced method callbacks are always: class name, followed immediately by the method name, followed by the amount of previously added (classname+methodname). For classes, this allows you to add as many object referenced classes and add methods which don’t override each other.
However I can't seems to be able to remove the action.
I tried to remove the action by putting following lines of code in function.php
function remove_bp_hierarchy(){
if (has_action('bp_actions')) {
echo $extension = new BP_Groups_Hierarchy_Extension;
remove_action('bp_actions', array( &$extension, '_register' ), 999);
} else {
}
add_action('bp_init','remove_bp_hierarchy', 999);
Is it something wrong with my remove_action or I use wrong method? Thanks and regards.
## Update
Found a page in which let we see a list of hooks and also hooked function in the page. I see that there's a function with the name _register which is the function I'm looking for. However, class address always change. I was thinking using the function found to do a preg_match on it and remove it when it found. this is super heavy. So is there other way of removing it? Thanks and Regards.
CodingBabyDotCom -
Long story short: you will have to traverse the $wp_filter array to remove the action.
You need a reference to the SAME instance that was used to create the action in order to remove it with the remove_action function. So the function you posted doesn't work because it is using a new instance.
Unfortunately bp_register_group_extension() creates only a temporary instance, so it can't be referenced by later functions.
The code in your comment will remove ALL actions at level 8, which means all group extensions. To remove only the one you want, iterate over each filter and check its type with:
is_a( $wp_filter['bp_actions'][8][$key], 'BP_Groups_Hierarchy_Extension' )

Adding a custom themable variable in theme_preprocess_page

I have read the docs over and over trying to wrap my head around this seemingly simple task. Basically, I have a template with a 'skip navigation' div hard-coded in html.tpl.php that I do not want on front-page.
My idea was to set a $vars['skiplink'] variable in theme_preprocess_page. Since this variable contains a few lines of html markup, I was aiming for something as seen in garland theme:
function garland_preprocess_page(&$vars) {
// Move secondary tabs into a separate variable.
$vars['tabs2'] = array(
'#theme' => 'menu_local_tasks',
'#secondary' => $vars['tabs']['#secondary'],
);
<snip>
I would like to have the html in a themable function or even a template, but I cannot even get this snippet to work:
/**
* Override or insert variables into the page template.
*/
function morin_preprocess_page(&$vars) {
// add skiplink markup
$vars['skiplink'] = 'hello world';
}
This generates a notice:
Notice : Undefined variable: skiplink in include() (ligne 14 in /var/dev/morin/www/sites/all/themes/morin/templates/html.tpl.php).
Can anyone slap me with a clue? I would really like to understand how to do this with both methods, ( template & function ). I'm also wondering if this should be done in a module?
I realise there are probably 10 ways to skin this cat, so any insights on pros/cons of methods used are welcome.
Ok I figured out I was using the wrong preprocess function, setting $vars['skiplink'] in preprocess_html is the way to go for top-level variables.I still have yet to figure out in a clear way how to associate this variable to a template file.
The preprocess hooks follow this pattern:
<theme name>_preprocess_<template name>
So if you want to modify the variables for "html.tpl.php" you want to use this hook:
<theme name>_preprocess_html(&$variables)
You are using preprocess_page but you are inserting the variable in the html.tpl.php.
You should either insert it in the page.tpl.php or rename your preprocess function, to add the variable to the html.tpl.php
And remember to clear cache if you didn't have the preprocess function defined already.
Update:
You seem to be missing a key point. Preprocess functions (along with the actual theme call) is how you make variables accessible in templates. Different preprocess functions are called for different templates, (..._page for page.tpl.php etc.)
Do you still have problems after using the correct preprocess function and clearing cache?

What's use of "#process" callback in drupal form api?

In drupal fapi there is an attribute "#process".what exactly does it?Why password field use it for field duplication instead of adding it with theming?
I want to use it for defining a new field type with hook_elements.
Edit:
here is my hook_elements:
function test_elemets() {
return array(
'test_field' => array(
'#input' => TRUE,
'#process' => array('test_field_process'),
)
);
}
and process callback:
function test_field_process($element, $edit, &$form_state, $complete_form) {
$element = array();
return $element;
}
as you see in process function I used $element=array() to see what happens.But the form is shown as it was before.why?
Read the Forms API documentation on the '#process' form element property.
It is an array of callback functions, each of which will be called with the the element definition array passed to it. The callback function can then act on the element definition array to turn it into a different (usually more complex) definition, like e.g. duplicating a password field while attaching an equality checking JavaScript file, or turning one combined 'radios' definition into an according amount of specific single 'radio' definitions, etc.
You will want to use it if you want to offer a complex form element (e.g. a combination of multiple 'standard' elements combined, or one with automatic addition of standard JavaScript helpers), but still keep the simple, declarative approach of the Forms API. (Look Ma - only one '#type' = 'myCrazyFormElement' array, that expands 'automagically' to something way more complex ;)
Doing this via the theming layer might be possible, depending on the use case, but would require more code, every time you need it.
api.drupal.org documentation on #process says:
An array of functions that are called
when an element is processed. Using
this callback, modules can "register"
further actions. For example the
"radios" form type is expanded to
multiple radio buttons using a
processing function.
Processing differs from theming in keeping within the form API. You can't alter a form array in the theme layer (at least not in D6). Password specifically, adds form_expand_ahah to #process. You could probably kludge most of that into the theme layer, but not this line:
$element['#cache'] = TRUE;
Because caching happens before the theme layer, that couldn't be done in the theme layer. More generally, while some of what happens in #process could happen in the theme layer, it couldn't all happen there because forms are more than front-end display; they're also back-end processing.

Resources