Can't drupal_execute('filter_admin_format_form') on hook_install? I'm attempting to configure an input format on hook_install() with the following code:

module_load_include('inc', 'filter', 'filter.admin');
$form_state = array(
  'values' => array(
    'name' => 'Full HTML',
    'format' => '2',
    'roles' => array(
      1 => 0,
      2 => 0,
      3 => 1,
    ),
  ),
);
$arg = filter_format_load(2);
drupal_execute('filter_admin_format_form', $form_state, $arg);

However this produces the error:

Filter format names need to be unique. A format named Full HTML already exists.

However if I run the same code on hook_init(), then it runs without error.

You can execute that code, but you need to give a unique name for the input format being saved.

As alternative, if you want to be sure there is an input format called Full HTML, you can save the input format in the database using db_query(), and using the code of filter_admin_format_form_submit(), the form submission hander for the form you are executing, as guideline.
The involved database tables are two: filter_formats, and filter_formats; the first contains the data about the input format, and the latter contains the data about the input filters associated with an input format. The relevant executed queries are the following ones.

  if (!$format) {
    $new = TRUE;
    db_query("INSERT INTO {filter_formats} (name) VALUES ('%s')", $name);
    $format = db_result(db_query("SELECT MAX(format) AS format FROM {filter_formats}"));
    drupal_set_message(t('Added input format %format.', array('%format' => $name)));
  }

db_query("DELETE FROM {filters} WHERE format = %d", $format);

  foreach ($form_state['values']['filters'] as $id => $checked) {
    if ($checked) {
      list($module, $delta) = explode('/', $id);
      // Add new filters to the bottom.
      $weight = isset($current[$id]->weight) ? $current[$id]->weight : 10;
      db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $format, $module, $delta, $weight);

      // Check if there are any 'no cache' filters.
      $cache &= !module_invoke($module, 'filter', 'no cache', $delta);
    }
  }

In Drupal 7, it would be easier, as you can call filter_format_save(), which always save the input format passed as argument, and eventually merge the format you passed as argument with the existing one.

The function that shows the error you are noticing is the form validation handler,  filter_admin_format_form_validate(), which contains the following code.

if ($result) {
  form_set_error('name', t('Filter format names need to be unique. A format named %name already exists.', array('%name' => $name)));
}

As the form validation handlers, and the form submission handlers are executed when you call drupal_execute(), the same error is returned, even when drupal_execute('filter_admin_format_form', $form_state, $arg) is called from hook_init(); it just happens that the error message shown with form_set_error() is not immediately visible when hook_init() is invoked, but the input format is not saved.
To notice that filter_admin_format_form_submit() executes the following code.

  $format = isset($form_state['values']['format']) ? $form_state['values']['format'] : NULL;
  $current = filter_list_format($format);
  $name = trim($form_state['values']['name']);
  $cache = TRUE;

  // Add a new filter format.
  if (!$format) {
    $new = TRUE;
    db_query("INSERT INTO {filter_formats} (name) VALUES ('%s')", $name);
    $format = db_result(db_query("SELECT MAX(format) AS format FROM {filter_formats}"));
    drupal_set_message(t('Added input format %format.', array('%format' => $name)));
  }
  else {
    drupal_set_message(t('The input format settings have been updated.'));
  }

Supposing that the form validation handler doesn't return an error, the form submission handler is not saving any data in the "filter_formats" table, if the input format is not new; in such case, the function executes the else part of the control statement, which just output a message.


How to remove "site email address on behalf of" and just keep the sender email address in "from:" part of a mail from drupal 7 I am getting from part of a mail sent from my drupal 7 website like below

From: (site mail address) On Behalf Of (sender mail address)

Here I want to remove everything except sender email address, how can I do this?

I have found following url but it is expired

http://www.fosspedia.com/drupal-remove-on-behalf-of-from-the-sent-mails/

Any help???

Thanks

Well you can write a simple module, and in your module insert this function. Here is where i got the idea

function yourmodule_mail_alter(&$message)
{
    $message['headers']['Sender'] = $message['headers']['From'];
}

If you want to go with quick sketch comment, in the link to completely get rid of the headers use

<?php
function mymodule_mail_alter(&$message) {
  unset($message['headers']['Sender']);
  unset($message['headers']['Errors-To']);
  unset($message['headers']['Return-Path']);
}
?>

There is also a module that can help out with this mail headers

  Control and modify any (almost any) mail header. Mail Headers allows
  you to:


Trying to make a custom region disappear upon user login, then reappear when user logs out I've looked everywhere for an answer to my problem, but can't find one. My goal is to collapse/force a custom region on my website to disappear when a user logs in, and then have it reappear when the user logs out.  Or, if it's not possible to collapse a region, to replace the region with an empty region that, through CSS, I have styled to display with zero height. Basically, I'm trying to make a custom region disappear upon user login, and then make it so the region reappears when the user logs out.

The reason for this is I'm putting the final touches on transforming the login block on my website so that instead of appearing in the sidebar, it appears as a horizontal login bar. I'm 90% of the way there. I created a custom region at the very top of the page to house the bar, and the bar kind of looks like the horizontal login bar you see on Facebook. But in reformatting the login block using CSS, I was only able to achieve the look I wanted by forcing the "Forgot your password?" and "Create a new account" links not to appear (otherwise, the links would reside between the password field and the "Log in" button, which looked weird).

But that left me with no login help links. To try to resolve this problem, I created a new region directly under the "username" and "password" fields to house the "Forgot your password?" and "Create a new account" links, which displays really nicely. But, of course, whenever someone logs in, those links remain on the screen, which is obviously weird.

I need to figure out a way to make the new region disappear when the user logs in, and to reappear when the user logs out. Also, I want the other regions in the header directly below the two new custom regions to move up once the region disappears so that there's not a gaping hole in the space where the region used to be. I'm pretty new to PHP, so what I've tried may be way wrong, but this is what I attempted, which didn't work -- it's the option of trying to swap out the region with the links with the empty region when a user logs in:

     <?php
        if(isset($username) == false):
        print render($page['nameofregion1']);
        else: ?>

        <?php print render($page['nameofregion2']);
        endif;
     ?>

where the CSS for 'region2style' is set to "height: 0px" to give it zero height. My suspicion is that I'm misusing the variable $user here, among other errors, but I can't seem to figure out what variable holds username info in Drupal. I'm sure there's a more elegant way of doing this, and if someone could point me in the right direction, I'd really appreciate it. Thank you.

Context is a great plugin for remodelling sections of your website - paired with Delta and the Omega theme, you can overhaul your entire layout based on nearly any condition without editing any code by hand.

There's a decent intro tutorial for Context and Delta over here.

But if that doesn't fit the bill, you're on the right track with your .tpl.php files. Checking for user login is quick, just remember to global the variable first:

<?php
global $user;

if ( $user->uid ) {
  // Logged in user
}
else {
  // Not logged in
}
?>

... and by inserting the desired code between braces you could easily toggle blocks, regions, messages and nearly anything else accessible from the template.

This is my "PRINT ALL THE THINGS!!" snippet, try it out for the $user variable:

<?php global $user; echo '<pre>'.print_r($user, true).'</pre>'; ?>

Good luck!


Accessing a selected value instead of key in drupal 8 I need to access values instead of keys from a custom form select field. To get the keys, I am using $form_state->getValue() but I don't know how to access the values. Kindly help.

Assuming that code is in a submit/validate method, you have the original form array available, so you can grab the options straight from the element definition:

$key = $form_state->getValue('foo');
$val = $form['foo']['#options'][$key];


Term page doesn't show nodes when terms are added in a field collection? I'm using field collection in my content type Recipe.
In my field collection, there is a term reference (ingredient) and a text field.

When I create a Recipe, I add terms (ingredients) with the field collection. But when I visit the term page (ingredient X), no recipes are listed even if this ingredient is used in a recipe.

I think the problem comes from Field collection : the term is linked to the field collection but not to the created content.

How do I display all the recipes linked to an ingredient  when I visit a term page ?

Sorry for my bad English, i'm not sure i'm clear.

This is because the default term page implementation in Drupal 7 is querying node relationships, it has no awareness of relationships to Field Collections that are related to Nodes (or potentially, other entities).

You would have to solve this yourself by using a module like Taxonomy Views Integrator, which lets you create Views and set them as the term page view instead of the default Drupal page callback which won't ever work in this scenario.

You can follow why you aren't getting hits from Drupal core here. Hence, you need to override this presentation.

So, if you use TVI, you'd want to create a View that selects field collections with relationships to terms and nodes, and give it a contextual filter of taxonomy term id from URL (assuming taxonomy/term/%tid path). This should get you results, and let you link to the node. I don't have a sandbox setup to try this out, so you may need to experiment on the View formula.


How to specify default formatter for custom field widget? I created a custom field widget implementing hook_field_widget_info(), created a custom formatter implementing hook_field_formatter_info() and also implemented hook_field_formatter_view() to generate the formatter's display.

Everything works as intended (validation, persisting values, formatter) with one glaring exception: I can't figure out how to make my widget use my formatter by default.

Every time I add a an iToggle field I need to manually change its formatter in Manage Displays for that content type.

Any ideas?

Here's my code:

function itoggle_field_field_widget_info() {
 return array(
   'itoggle' => array(
    'label' => t('iToggle Widget'),
    'field types' => array('list_boolean'),
    'settings' => array('display_label' => 1),
    'behaviors' => array(
      'multiple values' => FIELD_BEHAVIOR_CUSTOM,
    ),
  ),
);
}

function itoggle_field_field_formatter_info() {
  return array(
    'itoggle' => array(
    'label' => t('iToggle Widget'),
    'description' => t('Displays the field as an iToggle Widget'),
    'field types' => array('list_boolean'),
  ),
);
}

Thanks!

Short answer is you can't. You can only specify a default formatter for each field type itself in hook_field_info():

  default_formatter: The machine name of the default formatter to be used by instances of this field type, when no formatter is specified in the instance definition. This formatter must be available whenever the field type is available (i.e. provided by the field type module, or by a module the field type module depends on).


How to validate 3 or more fields when creating content in D7 I have a custom content type with 3 fields (integer). How can I check when content is created or edited that the sum of those three fields are equal to a predefined total. For instance, if the three fields represent percentages of a task to be completed, I would like to issue an error message if the sum of the three fields is not 100%

Create a module to add a validation handler to the form by implementing hook_form_alter():

function MODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'MY_FORM_ID') {
    $form['#validate'][] = '_MODULE_validate';
  }
}

Then define the handler function that checks the field values:

function _MODULE_validate($form, &$form_state) {
  // Check that the sum of the fields equals a predefined total
}

If you're not familiar with creating your own modules, but are comfortable with PHP, you could probably use the Field Validation module to add a custom PHP validator that does the same thing.


How do I git pull a dev branch? I'm trying to switch to the dev version of Views. Repository instructions worked and I was able to git clone Views.

However, listing the available branches with git branch -a only shows * 7.x-3.x
.

And trying to add a "dev" branch with pull returns an error:

$ git pull origin 7.x-3.x
From http://git.drupal.org/project/views
 * branch            7.x-3.x    -> FETCH_HEAD
Already up-to-date.
$ git pull origin 7.x-3.x-dev
fatal: Couldn't find remote ref 7.x-3.x-dev

What am I doing wrong?

I'm not a Git expert, but as I understand it all of the releases of the dev branch listed on the project page are made directly to the 7.x-3.x branch.  Of course you're free to create your own branches locally for your own needs, but the master-like branch, which includes all of the releases pushed to drupal.org, is always going to be that 7.x-3.x branch.

If you want to switch to one of the tagged releases, use git tag to get a list of all the releases.  Then, to check out the 7.x-3.1 release (for example), use git co 7.x-3.1.

If you intend to edit the code for this release, you can then create a new branch (as Git explains) by using git checkout -b mycustombranch.


using drupal_process_states() I'm trying to add dependencies to a set of fields, such that only one of the set can ever contain a value at any given time.

I see that drupal_process_states() does pretty much what I want, but I'd have to define it separately for each element. It looks like I'd be using it with hook_field_widget_WIDGET_TYPE_form_alter(), since that takes $elements as an argument?

Is there anything that might simplify this? Specifically, is there a function that can apply rules per fieldset rather than per widget?

I think I was confused about what drupal_process_states() does. It does not have to be declared like a hook or even invoked in my custom module. It is simply the machinery behind #states in the FormAPI. Simply using a hook_form_alter() and adding a #states array to the relevant fields is enough.


How do I display date and time for multiple time zones? I am webmaster at http://www.archerpoint.com. We would like to display our events in both Eastern and Pacific time. I only know how to control the system time zone or let the user set their own time zone, but I do not know how to display a single time entry as two separate time zones without hacking code or creating and displaying two separate entries, one for each time zone. Is there a simple solution for this?

Try to save date-time values in UTC format and while displaying them you can use format_date function

where you will need to pass timezone value to its parameter.


Automagically relating nodes of a single content type I have a content type (e.g. Target) which has a title and body. I will have about a 1000 nodes of this content type. I want to be able to create a view that renders not not only the title and body of this type of node, but also associated/related nodes.

I don't want to have to manually associate nodes (based on taxonomy or by adding an entity reference). Instead, I want the view to automatically search for the Title of a given node in the Body field of all other nodes of this type and associate those nodes that contain the given node's Title.

I'm new to Drupal, but believe I've gotten my head around the basics and have several Views configured and working. But I can't seem to find any guidance on achieving the above and not sure how to do that in Drupal/Views, although I know this is achievable in straight SQL.

Any ideas, advice?

Remeber that views is some kind a query builder, even better it gives you tools to alter its content, query and so on. See hook_views_query_alter


Is is possible to access views from a module file? I have created a view in drupal. My question is, is it possible to access the contents of the view or value stored in the view from the module file..
Need any details or code plss comment.

You can use drupal function views_get_view_result($name, $display_id = NULL)

$name : name of the view
$display_id : On the edit page for the view in question, you'll find a list of displays at the left side of the control area . e.g. 'MASTER', 'Page'

This function will return An array containing an object for each view item.

Reference :https://api.drupal.org/api/views/views.module/function/views_get_view_result/7


Infinite scroll change parameter My question is about drupal7 and infinite scroll module.
When I click on a button more news is loaded and html changes like this:

    Load More

My browser makes ajax request and receive some response:

view_name:blog
view_display_id:page
view_args:
view_path:about/media
view_base_path:about/media
view_dom_id:a2acec59ca7b252cfd911b770bc558bc
pager_element:0
page:2

I need to change page on frontend. How can I find where is this parameters set? OR can I change him on front end. I assume there is some hidden div related to this parameter, but I don't know how to find it.

I'm not sure I understand your question. If it helps: this is a view. You can access views list from /admin/structure/views  and  that specific view from /admin/structure/views/view/blog/edit/page

There you'll be able to change the output of page display.


Show menu even if node it's not in that menu Setup I got has two content types, page and article. Pages are normal pages and articles are news. On the site I also have three menus: main, sub and subsub. Main shows first level, sub shows second level items and subsub shows all below items.

Menu:

Front page
News
-Breaking news
About
-History
--Early years
-People in charge
Contact

Now when admin creates a news article it doesn't go to any menu. It's showed on the News page with view. And when user clicks the news it goes to the news article page where the news is showed fully. But now since the news article is not in menu, the submenu disappears. How can I "trink" Drupal to think that user is on sub page of News page -> The sub menu would visible?

In the settings for the menu item itself, there is a checkbox below "enabled" that says "expanded". Check this box for all items whose children you want to be visible all the time.


overlay submit feedback This might be a very simple question, but I can't figure out the answer.

I love the overlay module in drupal 7, but I am annoyed by the lack of visual feedback when a form is submitted in an overlay. eg. admin/structure/block, hitting submit doesn't give any indication that something is happening in the background.

I would love to know what I have to do to attach some behavior to the submit button of a form in an overlay that provides visual feedback that the form has been submitted (like greying out the overlay or something).

I just added a block with following code to the content region of my administration theme


Show old price with line-through I have Drupal 7, without Drupal Commerce modules installed, because we are nor e-commerce place. For some items, we need to show up two prices (old_price and new_price). Only for items for new_price filled I need to show up old_price line-trough or with an X on top. I suppose that I need to put some code in someplace, but where?

I have been looking for a module, but all modules are for commerce. I do not want to install commerce and all the pile of commerce modules just to add this feature.

First, create two fields-"Old price" and "new price". Second, use css text-decoration:line-through; on the old price field.

Edit:

Based on your comment and clarification, I would suggest using rules and rules bonus pack to look for the "new price field", then have it add a body class to the node.

Your rule will look something like

Event #1: "when content is created"
Event #2: "when content is updated"
Condition #1: "entity has field", then select your "new price" field
Condition #2: "Data value is empty" and enable "negate"
Action: "Add body class"

Then in your css add the strikethough based on the extra body class.

This is essentially how the Commerce price savings formatter module works, but without the overhead of using commerce.


Full HTML Formatter / WYSIWYG Not Working In Views 3? I have a Drupal 7 site that I've been plugging away at for the last few weeks, and I noticed that when I'm in Views and am trying to add a Global Text Area to the footer of my view (for a "Read More" link that goes to a custom page), the WYSIWYG formatter does not show up at all. The dropdown to pick formats appears, but none of them initiate TinyMCE.

The strange thing is that the Input Formats are configured just fine for the rest of the site and proper user roles. It works across all of the content types I have set up. So, my question is, how can I get this working so that I can put a link in the footer?

For sake of explaining things better, here's a screenshot. Note that this problem is only happening in Views.

I believe it's a lazy-load editor problem. The WYSIWYG libraries aren't being loaded on the parent page, so they are not available to the modal window. If you're using the WYSIWYG module with CKEditor, something like this should alleviate your issue.

<?php
  // Views support.
  if (module_exists('views') && $form_id == 'views_ui_edi') {
    // Load potential editor.
    foreach (filter_formats() as $format => $object) {
      if ($profile = wysiwyg_get_profile($format)) {
        wysiwyg_load_editor($profile);
        wysiwyg_add_plugin_settings($profile);
        wysiwyg_add_editor_settings($profile, 'advanced');
      }
    }
  }
?>

from http://drupal.org/node/356480#comment-1190907

and the patch located in -

http://drupal.org/node/356480#comment-4256204


How to have a view field that searches node title, body and everything about node I am looking at replacing the core search module with a custom view. I would want a field that lets users search all the content by keyword(s).

What's my best option, preferably a module that does this in a user friendly way.

You could try using Apache Solr backend. You can use the following modules:

http://drupal.org/project/search_api
http://drupal.org/project/apachesolr

Another solution is to use a module like "views_or" or "views_filters_populate".

Otherwise you could give a try to "search_autocomplete".

Good work!


How to Group fields, and duplicate them? I'm trying to create a type of buzz feed website where you can make a list of items.

If you set the body field setting to unlimited.
You get a "Add item" button.

You can duplicate the body field as many times as you want.

I want to duplicate a set of fields using the "Add item" button

title, image, description as one item.

How can I do this?

You can also go for the Multifield module. More details from its project page:

  This project seeks to provide a true compound field solution for Drupal 7. As much as I love Field collection, it still has to save actual entities, and can cause performance problems due to having to load all the referenced field collection entities on node, or parent entity load.

How to use multifield check listed links :

Video demo Demo
How Creating multiple value field groups .


Error message "responsive-utilities.less" not found I did set-up the sub-theme with less for the Bootstrap theme.
Following is the file structure,

Installed less using(Instruction followed from here),

$ npm install -g less

Then ran a following code to activate less,

$ lessc styles.less styles.css

Then following error shown,

Error message:

FileError: '../bootstrap/less/responsive-utilities.less' wasn't found.

Complete message as below.

FileError: '../bootstrap/less/responsive-utilities.less' wasn't found. Tried - /Applications/MAMP/htdocs/drupal7114/sites/all/themes/lsubtheme/bootstrap/less/responsive-utilities.less,/Applications/MAMP/htdocs/drupal7114/sites/all/themes/lsubtheme/bootstrap/less/responsive-utilities.less,../bootstrap/less/responsive-utilities.less in /Applications/MAMP/htdocs/drupal7114/sites/all/themes/lsubtheme/less/bootstrap.less on line 61, column 1:
60 @import "../bootstrap/less/utilities.less";
61 @import "../bootstrap/less/responsive-utilities.less";
62

What could be the reason for this error? Any idea? Thanks

Found the issue, actually it was my fault, I missed to paste the Bootstrap source file in the sub-theme folder. Because responsive-utilities.less is coming from /bootstrap/less/responsive-utilities.less as you can see in error message. Hence, previously bootstrap was missing, so this was error did appear.


Creating a thumbnail Navigation for a Flexslider I want to create this:

http://flexslider.woothemes.com/thumbnail-controlnav.html

Using Flexslider.

In Flexslider's Advanced Options I see there is an option to "Use as Navigation". I've tried setting another Flexslider slidehow (full of thumbnails) as the navigation but it doesn't seem to work right.

I just need to have a main slider and a slider under it full of thumbnails that acts as a navigation menu for the main slider. How can I do this?

Install Flexslider module
If you need to display images as a view, select "slider w/thumbnail controlnav pattern" option set in Flexslider display mode settings.
If you displays images a multi-valued image field, select "slider w/thumbnail controlnav pattern" for the field in Manage display tab.

Please note that controlNav pattern (you mentioned) is not the same as thumbnail slider.


How can I remove the remains of the Mass Contact module not properly uninstalled? I tried the Drupal 8 version of the Mass Contact module (8.x-1.0-beta2, released on June 2017).

As I was not fully satisfied, I decided to uninstall it.
Once done, I got errors when I tried editing a user account.

  The website encountered an unexpected error. Please try again later.
  Error: Call to undefined function mass_contact_opt_out_allowed_values_callback() in options_allowed_values() (line 89 of core/modules/options/options.module).

Digging a little bit, I found that the code to uninstall the module was not fully implemented: it leaves (at least) two configurations (field.field.user.user.mass_contact_opt_out and field.storage.user.mass_contact_opt_out) and a table in the database (d8_user__mass_contact_opt_out).

How can I get rid of that and have a clean uninstall?

This is an issue already resolved for the 8.x-1.x branch, as reported in Uninstall should remove mass_contact_opt_out field.

The code that has been added to the uninstall hook is the following one.

Drupal::configFactory()->getEditable('field.field.user.user.mass_contact_opt_out')->delete();
Drupal::configFactory()->getEditable('field.storage.user.mass_contact_opt_out')->delete();

If you have Drush installed, you can write those two lines in a file (for example, fix-module.php) and run it with drush php-script fix.module.php. You can also put the following code in a file next to the authorize.php file that comes with Drupal core, and access that file from the browser.

use Drupal\Core\DrupalKernel;
use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

// Change the directory to the Drupal root.
chdir('..');
$autoloader = (require_once 'autoload.php');

try {
  $request = Request::createFromGlobals();
  $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
  $kernel->boot();
  Drupal::configFactory()->getEditable('field.field.user.user.mass_contact_opt_out')->delete();
    Drupal::configFactory()->getEditable('field.storage.user.mass_contact_opt_out')->delete();
} catch (HttpExceptionInterface $e) {
  $response = new Response('', $e->getStatusCode());
  $response->prepare($request)->send();
  exit;
}


Hide/Show fields value in nodes I have a content type = Article. There I have 2 field. What I want is, If field 1 is empty or does not contain any value, replace this field with field 2, (with same css and html structure) else keep showing content of field 1 by default.

Is there any way to this in D8?

Create node--articles.html.twig and place it in your theme's templates folder.

{% if content.field_name.0 is empty %}

{{ content.field_name_other }}

{% else %}

{{ content.field_name }}

{% endif %}

Note:

content.field_name.0 gets the raw value


How can I form a Views query that retrieves all nodes that are referenced by a node in another content type? I have a content type of Artist. I also have a content type of Release. The Artist content type has a node reference field that points to the Release content type. This node reference field allows an Artist to have 1 or more Releases.

I created a view that displays fields from the Artist content type as a page. Let's call this view "Artist Page." Artist Page has a single argument of Node: Title and a path of artist/%. This works really well.

I would like to add another view for a block of Releases belonging to a particular Artist. I hope to display this block in the sidebar for Artist Page.

How can I form a Views query that retrieves all Releases that are referenced by an Artist?

(I am making my first non-trivial Drupal 6 site and I appreciate your patience. I am happy to RTFM but please tell me where to go!)

Ok, So the way to do this is with arguments and relationships.

Normally using the "Provide default argument" option would work but since you're not using the actual "artist" node you can't actually get the node id from the URL.

Also just an FYI, passing the title for a views argument is a bad idea because then the query is doing a lookup based on text instead of a numeric value such as the node id which is better on performance.

But anyways the solution to your problem is add the same argument to your block view as you did to your "artist" page view. This should be the node title argument. Now add a relation to your view. The relationship you want to add is the content: [name of node reference field] relationship.

Now you can add what ever fields to your view that you would want to include from the "release" content type but now you will see you get a relationship option in the field option. When you want to display fields from the "release" content type just be sure to select the [node reference] relationship.

Also we need to do one more thing. Which is getting the proper argument to be picked up by your block view. This is a bit trickier mainly because of what I mention earlier which is that you're passing the node title as an argument. So now you can edit your Node: Title argument and you should see the "option to take if the argument is not present" select the "provide default argument" and select the php code option. In there you want to paste this piece of code.

return arg(1);

Now save your view and place that block on the page and visit the artist/% page and you should now see what ever fields you want to use. This php code is telling your block view to pick up the artist/% argument from the url.

A couple of things to lookout for:

php code in the views is bad, I just mentioned that here as a quick fix to your problem.
When using relationship be sure to select the relationship option only when you want to display a field from the "related" item. In other works if you want to display the title of the related node select node title and be sure the relationship is selected. If you want to display the title of the node being passed in on the argument select node title just don't select any relationship.

Hope this is helpful, is a long post but relationships can be confusing.

Hope this helps.


How do I get Captcha to reappear in my registration form if an error was detected after submission? I'm using Drupal 7 and have added an image Captcha as part of the registration process. The Captcha works just fine but if the form is submitted with an error, it no longer appears with the rest of the form when the registration page reloads. How do I make sure it always reappears? Thanks.

It's in module settings. Under Persistence , you can set CAPTCHA to appear:

always,
once per form,
once per session.

It used to default to always, but as far as I remember there was an issue to change default. Probably now it defaults to once per form or once per session. It should be enough to manually change it to always.


How to Filter views result by current logged in user's role I know it can be done using PHP Code I am looking an option which will be using configurations.

Try adding view relationship to "Content: Author", and then add contextual filter for field "(author) User: Roles".


Trouble installing on localhost I am having trouble installing drupal on my localhost, using PHP Version 5.6.0-1, system Linux notosh 3.16-2-amd64 #1 SMP Debian 3.16.3-2 (2014-09-20) x86_64
Installing standard 7.31, no distro.
Upon completion cannot login as user1 with password to access admin interface.

I just used drush to install on localhost and it solved all my problems.
At present my PHP Version 5.6.4-1, it works fine.


posting a comment on cached page I am a bit confused now - is it normal behavior that posting an anonymous comment on cached page invalidates ALL cached pages for whole site for current anonymous user? Beacouse that is exactly what I am experiencing now. Moreover, current anonymous user is not able to cache pages by visiting them in browser. Is it a bug or is it some sort of a cookie? Thank you for answers.

UPDATE1: I created fresh install, set up a few testing nodes with anonymous commenting enabled and it seems that after submitting comment, drupal adds a cookie. In response headers there shows no-cache on all pages.

UPDATE2: I tried @mikeytown's suggestion and tested out alternative database cache http://drupal.org/project/adbc and it turned out to work ok with anonymous comments. After posting a comment on a cached page - all other precached pages are served from database for current anonymous visitor. This is what I expected as default behavior from core drupal cache. As a sidenote - in addition to that I tested content refresh module http://drupal.org/project/content_refresh which flushes cache of the page immediately where comment is posted, which turned out to be working pretty good.

Next I tested submitting comments using ajax http://www.test.eotazky.sk/admin/config/content/ajax_comments . This solution created a session which disabled access to cached pages to current anonymous user. Clearing browser's cache helped.

I tested also other forms on cached pages like poll or closedquestion which use ajax to submit forms and it seems to me that all ajax submitted forms set a session that disable access to cached pages for current anonymous user.

You could give Alternative Database Cache a try. Set the minimum cache lifetime and you should see pages cached within the cache lifetime window not being cleared. Clearing the cache when a comment is saved is default behavior; look at the bottom of the comment_form_submit function if you wish to see the call to cache_clear_all.

As for the cookie, it is most likely being set because of calls to drupal_set_message; also noted is comment_form_submit calls user_cookie_save


How to compute fields from different content types and then show the result in Views table Is there a way to compute fields from different content types then display the result in Views table?

I will use those fields in a given formula.

Ya definitely,

Include those fields in views, Take another field Global: Custom text OR Global: Math expression and that's field setting text or expression, use previous field value as a token as per your formula. Make sure this field will be below the all other field that you will use in formula. You may exclude the fields that you use in formula if not want to display.


Is it possible to alter html_head using hook_page_attachments_alter() per node? Is it possible to alter html_head using hook_page_attachments_alter() per node? I need to attach different <script> tags to a list of nodes. I am able to add it to each node, but all gets overridden with the last alteration.
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => 'faq_page', 'status' => 1]);

foreach($nodes as $node) {
  $description = [
    [
      '#tag' => 'script',
    ],
    // …
  $page['#attached']['html_head'][] = [$description, 'description];
}

Yes, when you get the current node.
/**
 * Implements hook_page_attachments_alter().
 */
function MYMODULE_page_attachments_alter(array &$attachments) {

  $node = \Drupal::routeMatch()->getParameter('node');

  if ($node instanceof \Drupal\node\NodeInterface) {

    $attachments['#attached']['html_head'][] = [
      [
        '#tag' => 'script',
        '#value' => 'alert("' . $node->getTitle() . '")',
      ],
      'MYMODULE_foobar',
    ];
  }
}

If this really should be in a foreach, you need to ensure to give each tag an unique key.
foreach ($nodes as $node) {
  $description = [
    [
      '#tag' => 'script',
    ],
    ...
  ];
  $page['#attached']['html_head'][] = [$description, 'description_' . $node->id()];
}


Views Output field as a link - Two tokens, use only one of them I have content type which has field_pdf.
I have made view to show content and there is a field which has set: Output field as a link.
In link path settings I have two tokens: [field_pdf][path]. Idea is to link field either straight to PDF (if there is PDF file in node) or to content node.

How to get view to use only [field_pdf] when this field_pdf has content and not use [path] at all?

Now I'm getting double url for example: http://url.com/pdf-file.pdfhttp://url.com/pdf

Modules You Need:

Views
Views PHP

Assuming your content type is having these fields:

The VIEWS Code:
Simply go to admin/structure/views/import and then Import the below mentioned code:
$view = new view();
$view->name = 'pdf';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'PDF';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'PDF';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Content: PDF */
$handler->display->display_options['fields']['field_pdf']['id'] = 'field_pdf';
$handler->display->display_options['fields']['field_pdf']['table'] = 'field_data_field_pdf';
$handler->display->display_options['fields']['field_pdf']['field'] = 'field_pdf';
$handler->display->display_options['fields']['field_pdf']['label'] = '';
$handler->display->display_options['fields']['field_pdf']['exclude'] = TRUE;
$handler->display->display_options['fields']['field_pdf']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['field_pdf']['alter']['path'] = '[field_pdf][path]';
$handler->display->display_options['fields']['field_pdf']['element_label_colon'] = FALSE;
/* Field: Global: PHP */
$handler->display->display_options['fields']['php']['id'] = 'php';
$handler->display->display_options['fields']['php']['table'] = 'views';
$handler->display->display_options['fields']['php']['field'] = 'php';
$handler->display->display_options['fields']['php']['label'] = '';
$handler->display->display_options['fields']['php']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['php']['use_php_setup'] = 0;
$handler->display->display_options['fields']['php']['php_output'] = '<?php
if (isset($data->field_field_pdf[0][\'rendered\'][\'#markup\'])) {
    $pdf_url = $data->field_field_pdf[0][\'rendered\'][\'#markup\'];
    print $pdf_url;
} else {
    global $base_url;
    $node_url = $base_url . \'/node/\' . $data->nid;
    print $node_url;
}
?>';
$handler->display->display_options['fields']['php']['use_php_click_sortable'] = '0';
$handler->display->display_options['fields']['php']['php_click_sortable'] = '';
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'pdf' => 'pdf',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'pdf';

I'm sure you might be having some dummy content for that content-type, if not then do create couple of ones. Some with values in field_php and some with not!
and Voila! Here is your required output:

Updated Code:
$view = new view();
$view->name = 'pdf';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'PDF';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'PDF';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Content: PDF */
$handler->display->display_options['fields']['field_pdf']['id'] = 'field_pdf';
$handler->display->display_options['fields']['field_pdf']['table'] = 'field_data_field_pdf';
$handler->display->display_options['fields']['field_pdf']['field'] = 'field_pdf';
$handler->display->display_options['fields']['field_pdf']['label'] = '';
$handler->display->display_options['fields']['field_pdf']['exclude'] = TRUE;
$handler->display->display_options['fields']['field_pdf']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['field_pdf']['alter']['path'] = '[field_pdf][path]';
$handler->display->display_options['fields']['field_pdf']['element_label_colon'] = FALSE;
/* Field: Global: PHP */
$handler->display->display_options['fields']['php']['id'] = 'php';
$handler->display->display_options['fields']['php']['table'] = 'views';
$handler->display->display_options['fields']['php']['field'] = 'php';
$handler->display->display_options['fields']['php']['label'] = '';
$handler->display->display_options['fields']['php']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['php']['alter']['path'] = '[php]';
$handler->display->display_options['fields']['php']['alter']['absolute'] = TRUE;
$handler->display->display_options['fields']['php']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['php']['use_php_setup'] = 0;
$handler->display->display_options['fields']['php']['php_output'] = '<?php
if (isset($data->field_field_pdf[0][\'rendered\'][\'#markup\'])) {
    $pdf_url = $data->field_field_pdf[0][\'rendered\'][\'#markup\'];
    print $pdf_url;
} else {
    global $base_url;
    $node_url = $base_url . \'/node/\' . $data->nid;
    print $node_url;
}
?>';
$handler->display->display_options['fields']['php']['use_php_click_sortable'] = '0';
$handler->display->display_options['fields']['php']['php_click_sortable'] = '';
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'pdf' => 'pdf',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'pdf';

Let me know if you need anything else from this.
Cheers!


Switching theme for comments as well as nodes (ThemeKey?) I'm building a site based on Advanced Forum. I need each forum to display a different theme. ThemeKey does this so nicely with a trigger for which forum taxonomy is in effect, but does not seem to invoke that theme when entering or viewing comments to a post in that forum. So main pages and posting pages for a given forum are in the chosen theme for that forum, but viewing or replying to comments within that forum revert back to the default theme, which is very jarring.

Breadcrumbs know forum you are in even when viewing or replying to comments to posts in that forum, I cannot find a way to make ThemeKey trigger when dealing with comments to posts in forums, as well as it does for main pages and posts within that forum.

Any guidance would be appreciated.

You may use hook_custom_theme if you want to set theme for the comments pages.


Programmatically use token filter I'm attempting to use the token filter programmatically inside a .theme file like so.

function mytheme_preprocess_block(&$vars){
  $token = Drupal::token();
  $vars['label'] = $token->replace('[node:title]');
}

I looked at https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Utility%21Token.php/function/Token%3A%3Areplace/8.2.x for information.
However when I output $vars['label'] all it produces is [node:title] as if no replacement occurred at all. How would I programmatically initiate the token filter?

UPDATE: As a test I attempted using another method of token to make sure anything was happening at all by using $token->scan('[node:title]'); and it did spit out

  array(1) { ["node"]=> array(1) { ["title"]=> string(12) "[node:title]"
  } }

So I know I invoked the token class properly at least

UPDATE: It appears that the token replace was working it just didn't recognize [node:title]. Using [site:name] did produce the expected result. How would I be able to get [node:title] to work? Do I need to supply it with that data?

Data about the node needed to be supplied as a parameter to the replace method.
It worked once I used

$node = \Drupal::routeMatch()->getParameter('node');
$vars['label'] = $token->replace($vars['label'],['node' => $node]);


Form submit : how to pass parameters? I have a form with a submit button :

$form['my-custom-submit'.$i] = array(
    '#name' => $nid,
    '#type' => 'submit',
    '#value' => 'Delete Node',
    '#submit' => array('::deleteNode'),
);

This submit button calls this function :

public function deleteNode(array &$form, FormStateInterface $form_state, $nid)
{
    // My Delete function($nid)
    drupal_set_message('Delete : '.$nid, 'status');
    $form_state->setRedirect('my-route');
}

How can I pass the $nid parameter to my deleteNode function ?
Or if there is a way to get the '#name' in my function, it could be perfect too.
I cannot pass it through a $form_state->getValue('abc') because it is a list of incremented ids : $form['my-custom-submit'.$i].

I have searched google for 4 hours without finding, but I'm pretty sure that there is a simple way to accomplish this (newbie).

Thanks in advance.

Edit :
I found that the '#name' and value of the submit are passed to my function, I can get it like this :

public function deleteNode(array &$form, FormStateInterface $form_state)
{
    $last_nid = '';

    foreach ($form_state->getValues() as $key => $value) {
      $last_nid = $key;
    }
    // My Delete function($last_nid)
    drupal_set_message('Delete : '.$last_nid, 'status');
    $form_state->setRedirect('my-route');
}

Which isn't really elegant but does the job.
Is there a better way to get it ?

You can try this. Set the node id in the form element

    '#nid' => $nid,

and use FormState::getTriggeringElement to get the triggering element and the property #nid:

  public function deleteNode(array &$form, FormStateInterface $form_state) {

    $trigger = $form_state->getTriggeringElement();
    $nid = $trigger['#nid'];

In some cases you have to get the triggering button from the parent property:

    $clicked_button = end($form_state->getTriggeringElement()['#parents']);


Do you have an example of hook_menu() access callback? I have downloaded the examples project, but in the menu_example module all the access callback are set to true.. hard to understand how it works.

In my example, my meno entry should be visible on nodes, but only for roles that have the permissions to edit his own nodes.

I cant find an example a bit more verbose of an access callback.

Do anyone have one?

Drupal is itself an example of how to write code.

The easier example is aggregator_menu(), which contains the following code.

  $items['admin/config/services/aggregator'] = array(
    'title' => 'Feed aggregator',
    'description' => "Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized.",
    'page callback' => 'aggregator_admin_overview',
    'access arguments' => array('administer news feeds'),
    'weight' => 10,
    'file' => 'aggregator.admin.inc',
  );
  $items['admin/config/services/aggregator/add/feed'] = array(
    'title' => 'Add feed',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('aggregator_form_feed'),
    'access arguments' => array('administer news feeds'),
    'type' => MENU_LOCAL_ACTION,
    'file' => 'aggregator.admin.inc',
  );

In this case, the access callback is the default (user_access()), and the access arguments are an array containing the string for the permission. The code cannot check more than a permission; if the permissions to check are two, or the conditions to check are not just permissions, then the access callback should be a different one, including a custom one.

node_menu() define some menus that use an access callback different from the default one. The function contains the following code.

  foreach (node_type_get_types() as $type) {
    $type_url_str = str_replace('_', '-', $type->type);
    $items['node/add/' . $type_url_str] = array(
      'title' => $type->name,
      'title callback' => 'check_plain',
      'page callback' => 'node_add',
      'page arguments' => array($type->type),
      'access callback' => 'node_access',
      'access arguments' => array('create', $type->type),
      'description' => $type->description,
      'file' => 'node.pages.inc',
    );
  }

The function that is defined as access callback (node_access()) is the following one:

function node_access($op, $node, $account = NULL) {
  $rights = &drupal_static(__FUNCTION__, array());

  if (!$node || !in_array($op, array('view', 'update', 'delete', 'create'), TRUE)) {
    // If there was no node to check against, or the $op was not one of the
    // supported ones, we return access denied.
    return FALSE;
  }
  // If no user object is supplied, the access check is for the current user.
  if (empty($account)) {
    $account = $GLOBALS['user'];
  }

  // $node may be either an object or a node type. Since node types cannot be
  // an integer, use either nid or type as the static cache id.

  $cid = is_object($node) ? $node->nid : $node;

  // If we've already checked access for this node, user and op, return from
  // cache.
  if (isset($rights[$account->uid][$cid][$op])) {
    return $rights[$account->uid][$cid][$op];
  }

  if (user_access('bypass node access', $account)) {
    $rights[$account->uid][$cid][$op] = TRUE;
    return TRUE;
  }
  if (!user_access('access content', $account)) {
    $rights[$account->uid][$cid][$op] = FALSE;
    return FALSE;
  }

  // We grant access to the node if both of the following conditions are met:
  // - No modules say to deny access.
  // - At least one module says to grant access.
  // If no module specified either allow or deny, we fall back to the
  // node_access table.
  $access = module_invoke_all('node_access', $node, $op, $account);
  if (in_array(NODE_ACCESS_DENY, $access, TRUE)) {
    $rights[$account->uid][$cid][$op] = FALSE;
    return FALSE;
  }
  elseif (in_array(NODE_ACCESS_ALLOW, $access, TRUE)) {
    $rights[$account->uid][$cid][$op] = TRUE;
    return TRUE;
  }

  // Check if authors can view their own unpublished nodes.
  if ($op == 'view' && !$node->status && user_access('view own unpublished content', $account) && $account->uid == $node->uid && $account->uid != 0) {
    $rights[$account->uid][$cid][$op] = TRUE;
    return TRUE;
  }

  // If the module did not override the access rights, use those set in the
  // node_access table.
  if ($op != 'create' && $node->nid) {
    if (module_implements('node_grants')) {
      $query = db_select('node_access');
      $query->addExpression('1');
      $query->condition('grant_' . $op, 1, '>=');
      $nids = db_or()->condition('nid', $node->nid);
      if ($node->status) {
        $nids->condition('nid', 0);
      }
      $query->condition($nids);
      $query->range(0, 1);

      $grants = db_or();
      foreach (node_access_grants($op, $account) as $realm => $gids) {
        foreach ($gids as $gid) {
          $grants->condition(db_and()
            ->condition('gid', $gid)
            ->condition('realm', $realm)
          );
        }
      }
      if (count($grants) > 0) {
        $query->condition($grants);
      }
      $result =  (bool) $query
        ->execute()
        ->fetchField();
      $rights[$account->uid][$cid][$op] = $result;
      return $result;
    }
    elseif (is_object($node) && $op == 'view' && $node->status) {
      // If no modules implement hook_node_grants(), the default behavior is to
      // allow all users to view published nodes, so reflect that here.
      $rights[$account->uid][$cid][$op] = TRUE;
      return TRUE;
    }
  }

  return FALSE;
}

There are three points to notice:

The arguments declared with "access arguments" will be passed to the function in the same order; the function uses a third parameter because it is not used only access callback.
The function returns TRUE if the user has access to the menu, and FALSE if the user doesn't have access to the menu.
An access callback can also be used when a menu should be shown only in specific circumstances.


How is JavaScript included in Drupal 7? My site is built on Drupal 7, and a number of my .js scripts are throwing this exception: Uncaught TypeError: Property '$' of object [object Window] is not a function. After some research, I think this is related to the new jQuery namespace update, but since we didn't write the scripts, I'd rather remove them than make changes.

I've traced the references to the $scripts variable in html.tpl.php, but haven't been able to trace back any farther. I've examined .info files for additions to scripts[], drupal_add_js(), drupal_add_library(), preprocess and process function calls, and found nothing.

Has anyone had similar issues with removing JS file references, and could you give me a rundown on Drupal's script inclusion process? I found the methods above digging through docs and help sites, but I'm still not clear on how it all comes together (i.e. if scripts[] variable additions are added before drupal_add_js() calls, etc.).

if scripts[] variable additions are added before drupal_add_js() calls, etc

The JavaScript files used by a theme, and defined with scripts[] directives are added in _drupal_theme_initialize(), using the following code.

  // Do basically the same as the above for scripts
  $final_scripts = array();

  // Grab scripts from base theme
  foreach ($base_theme as $base) {
    if (!empty($base->scripts)) {
      foreach ($base->scripts as $name => $script) {
        $final_scripts[$name] = $script;
      }
    }
  }

  // Add scripts used by this theme.
  if (!empty($theme->scripts)) {
    foreach ($theme->scripts as $name => $script) {
      $final_scripts[$name] = $script;
    }
  }

  // Add scripts used by this theme.
  foreach ($final_scripts as $script) {
    drupal_add_js($script, array('group' => JS_THEME, 'every_page' => TRUE));
  }

_drupal_theme_initialize() is indirectly called from theme(), l(), contextual_preprocess(), and ThemeRegistry::initializeRegistry().

As each JavaScript file added to a page has its own group, with its own weight, it doesn't generally have importance which file is added first. If you really need to be sure a file is included before another one, you should define its group, and its weight, consider that files are included following this order:

First by scope, with 'header' first, 'footer' last, and any other scopes provided by a custom theme coming in between, as determined by the theme
Then by group
Then by the 'every_page' flag, with TRUE coming before FALSE
Then by weight
Then by the order in which the JavaScript was added


Mediafront Youtube playlist feed playlist problem I installed the MediaFront 7.x-2.0-rc2 module and MediaFront: Youtube Playlist Feeds 7.x-2.0-rc2.

I want a player with the playlist on the side.  The feed imports fine and creates the nodes.  In my player, I have the video, but for the playlist, I have blank videos, each with a "Sample Title" title.  When I click on a blank video, it correctly plays the video in the main player, so the view knows about the other videos.

What am I missing?

this i found useful: https://gdata.youtube.com/demo/index.html

which got me a functioning feed URL for MediaFront and so I still can create a playlist as a MediaFront preset. But its still another problem, yet to be solved, to get that MediaFront YouTube playlist preset to show as a node!!

Because when I add the same URL into an empty preset, its fails, complaining URL is bad!!

good luck and let me know how it goes for you ;-)

Richard


View displays no results for roles without Bypass Content Access For some reason one of my Views displays no results when I use my moderator role, but it does when I use the administrator role. The role permissions are exactly the same, except for the "Bypass Content Access" permission.

When I display content of type A everything is displayed like it should. But as soon as I add a "referenced entity" relationship from A to type B, nothing is displayed and the view uses the "No results behaviour".

When I create a view displaying only type B, both roles can see everything just fine.

I'm using Content Access and Organic Groups. I granted the roles the same permissions. I also set the View permissions to None.

Does anyone have a clue why this could be?

Based on my experience user1 (admin) bypasses everything , no matter what permissions the role administrator has granted (check to believe) , so just because you can see something in a view as admin and having same permissions for administrator and another role does not permits users in that role to access what admin can.

so check to see what what permissions may lead to accessing this view , this permission might be unchecked for admin but still bypassing it.


How can I grant users permissions to edit certain views (add/remove fields in a view) in drupal? We offer a Drupal site to our client with a set of views. The client wants to edit a (predefined) set of views. So, say for example the application got 3 views. The client is allowed to edit one of them.

I have been looking for a module to take care of this but couldn't find any. I was hoping there would be a module which would take the Views tags into account, so you can set permissions on this tag. Say I assign the tag 'Client' to a view. I then can assign the edit permission for a certain role on this tag.

How would you solve this or is there already a solution available?

Thanks!

If your client need only to edit the basic settings of some views (header, footer, title, or empty text...), you should give a try to the Views UI: Edit Basic Settings module. It allows you to define which views are editable by a certain role.


Adding a unique key to Drupal column I'm just doing a one-off script, but I'm wondering if there's a correct "Drupal way" to alter a table and a unique key.

For example, this is essentially the query I want to do:

ALTER IGNORE TABLE `node_revision` ADD UNIQUE(`hash`);

And then if I later wanted to remove the unique index on hash, how would I also do that?

Does it have something to do with updating the database schema? or possibly db_change_field()?

db_add_unique_key() is the function you're looking for.


How do I show content based on relationship? There are two users A & B. A is in "friends" type relation with B. Basically what i want to achieve with this is that i want to display blog posts made by B (or any friends of A) to A.
Now the content should be displayed inside a block on user A's profile page. (Just like facebook wall where you get latest updates from friends).

I know i can achieve this using Views but can anyone point me in correct direction?

User Relationships module is what i am presently using.

Create a new View with whatever fields, teasers that you want.
Click on the "Advanced" tab and that should open up a whole bunch of
sections.  You need the "Relationships" section. Click "Add". In the
popup find "User Relationships: Requester user" that's your key.
Now you need to validate who that Requester is. You do it through
the Contextual Filters. Click "Add" and find "User Relationships:
Requester user", and inside it's options select "Current User".
Now you need to filter content that is written by "friends of" the
current user. For that you need to add another relationship "User Relationships: Requestee user" which is a relationship of "User Relationships: Requester user" that you have already established.
Under "Filter Criteria" click "Add" - find "node Author", and
in it's options choose "requestee".

These are the basic directions, you can play around with it under different combinations.


Prevent enter to submit form / disable enter I am trying to prevent to submit the form when a user is pressing enter. I am trying to do so in a form that is also using ajax. I want to have the user click on submit after filling out all the necessary stuff and not have them accidentally press enter and have the form submitted.

I have the code below; the alertbox is popping up when pressing 's' for example. also when I press enter I can get a alertbox popping up. But it is not preventing to submit the form.

$("#edit-searchfield").keydown(function(e){
  var code = e.which; // recommended to use e.which, it's normalized across browsers
  if (code == 13) {
    e.preventDefault();
    return false;
  }
  if (code == 83 || code == 13 || code == 188 || code == 186) {
    alert("I am an alert box!");
  }
});

And the answer is :-)

$form['#attributes'] = array('onsubmit' => 'return false');

or alternatively (the above will disable submit all together)

  $('#edit-searchfield').keypress(function(event) {
   if (event.keyCode == '13') {
       event.preventDefault();
   }
});


Pathologic relative path on multisite Old multisite subsite relative path to image (in block/Full HTML with CKeditor and on localhost/XAMPP):

/sites/site1.localhost/files/image.png

New multisite path (what I'm trying to achieve):

/sites/site2.localhost/files/image.png

So, in Full HTML input settings for Pathologic, we select the 3rd option Relative path and add lines:

/sites/site1.localhost/
/sites/site2.localhost/

And nothing happpens, it just strips the /sites/site1.localhost/ from path and now the path to image is just:

/files/image.png

How do I make it the /sites/site2.localhost/?

Solved running SQL query in phpMyAdmin

UPDATE field_data_body  SET body_value = REPLACE(body_value,'src="/olddirectory','src="/newdirectory');

Source article: http://www.coolestguidesontheplanet.com/downtown/changing-image-paths-drupal-subdirectory-installation


Expose Custom Form in Block A form was created with codes in a custom module, with three items that must be filled. After submission, the code will do it's magic and return the result on the same page, below the form.

I'll like to have the form alone in a block so that it can be placed anywhere on the websites and when filled from there, it will redirect to the main page and show the results.

I don't know which way to go please.

First thing you have to do is to move the form into it's own block. That will require a hook_block_info(), to define the block, and hook_block_view(), to create the content of the block.

https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_info/7.x
https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_view/7.x

Define the block:

function my_module_block_info() {
  $blocks['your_block'] = array(
    // info: The name of the block.
    'info' => t('Your Block Name'),
  );

  return $blocks;
}

Then create the content. You can use another function that contains the form.

function my_module_block_view($delta = '') {
  // This example is adapted from node.module.
  $block = array();

  switch ($delta) {
    case 'your_block':
      $block['subject'] = t('My Form');
      $block['content'] = drupal_render(drupal_get_form('my_module_myform_form'));
      break;
  }
  return $block;
}

function my_module_myform_form() {
  // Your form will go here.
  $form['my_value'] = array
  (
    '#type' => 'select',
    '#options' => array('' => '---', 1 => t('One'), 2 => t('Two'), 3 => t('Three')),
    '#required' => TRUE,
  );
  $form['submit'] = array
  (
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}

Next is to create a submit callback which redirects to your page. You don't need to register the callback. Drupal looks for the form function name with '_submit' appended.

function my_module_myform_form_submit($form, &$form_state) {
  $form_state['redirect'] = 'some/path/' . $form_state['values']['my_value'];
}

And then we need to create the page:

function my_module_menu()
{
  $menu['some/path/%'] = array
  (
    'title' => 'My form submitted values',
    'page callback' => 'my_form_submitted_value_callback',
    // array(2) will pass the value of the wildcard to the callback function
    'page arguments' => array(2),
    'access callback' => TRUE,
  );
  return $menu;
}

function my_form_submitted_value_callback($submitted_value)
{
  return t('The value you submitted was: @value', array('@value' => $submitted_value));
}

If you need more than one value, there are more methods on this page like using $_GET and session variables:
https://www.drupal.org/node/1990276

Sources:

Form within a block
https://www.drupal.org/node/2064545
https://www.drupal.org/node/1990276
How to create a new block programmatically?


Selecting the right pattern for adding in robots.txt I've some views with exposed filters but I find that Googlebot is indexing them. In short I don't want any of those Views content by generated exposed filters to be seen by Google.

This page has listed more about it.

I want a pattern which should work for almost all views by restricting access to content generated by changing exposed filters.

Will this cause any issues?:

Disallow:/*&sort_order=*

Assuming we always specify sort order in Views. Is there any other module(s) which may generate url containing this parameter?

Adding the line you suggest to you site's robots.txt will stop googlebot from crawling the URLs that contain this string.

However, what attributes modules add to the URL is up to the module.  You need to examine the source code of the modules you use to avoid any conflict. I doubt there is anyone here with encyclopedic knowledge of what attributes every module use (there are more than 20000 on Drupal.org).

Instead of searching through modules for possible conflicts, I would invent a "magic" string that is pretty much guaranteed to be unique or not used for any other purpose by a Drupal module (e.g. "dontcrawlme") and add that "magic" string to the path to the views I don't want crawled, or add a dummy attribute with "magic" string as name to those views, then Disallow any crawling of an URL containing the "magic" string. This is simpler and more robust than relying on sort_order= being unique for exposed filters in Views.

You need to take care not to overwrite your custom additions to robots.txt when you do a minor upgrade of the Drupal core.

Note that wildcards is not part of the Robot Exclusion Standards (but are supported by googlebot and bing), so don't expect any rule with wildcards to be widely recognised by robots.


How to override the default zen html template depending on a node type? I have a themes which inherit from zen template. The zen template has an html.tpl.php, and I would like to override that html.tpl.php for one content type.

Let's say my theme name is test and my content type is called foo, I have tried the following code snippet into my template.php located in my test theme

function test_preprocess_html(&$vars){
  if (!empty($vars['node'])) {
    $vars['theme_hook_suggestions'][] = 'html__node_' . $vars['node']->type;
  }
}

Then I have created my html template named html--node-foo.tpl.php in the templates folder.

And, it doesn't works! I keep having the default zen html template loaded.

Here is the source of the html.tpl.php file in the zen templates folder

Ps: the following snippet works for overriding the pages templates depending on node type. Why does the above snippet doesn't works?

function test_preprocess_page(&$variables) {
  if (!empty($variables['node'])) {
    $variables['theme_hook_suggestions'][] = 'page__node_' . $variables['node']->type;
  }
}

Jonathan, your missing an underscore...

function test_preprocess_html(&$vars){
  if (!empty($vars['node'])) {
    $vars['theme_hook_suggestions'][] = 'html__node__' . $vars['node']->type;
  }
}

Your get it if you see whats suggested already be doing a var_dump($vars).

This has nothing to do with the Zen theme, it's just core functionality.

To understand how this is formed you can take a look at the theme_get_suggestions() function in theme.inc

/**
 * Generate an array of suggestions from path arguments.
 *
 * This is typically called for adding to the 'theme_hook_suggestions' or
 * 'classes_array' variables from within preprocess functions, when wanting to
 * base the additional suggestions on the path of the current page.
 *
 * @param $args
 *   An array of path arguments, such as from function arg().
 * @param $base
 *   A string identifying the base 'thing' from which more specific suggestions
 *   are derived. For example, 'page' or 'html'.
 * @param $delimiter
 *   The string used to delimit increasingly specific information. The default
 *   of '__' is appropriate for theme hook suggestions. '-' is appropriate for
 *   extra classes.
 *
 * @return
 *   An array of suggestions, suitable for adding to
 *   $variables['theme_hook_suggestions'] within a preprocess function or to
 *   $variables['classes_array'] if the suggestions represent extra CSS classes.
 */
function theme_get_suggestions($args, $base, $delimiter = '__') {

  // Build a list of suggested theme hooks or body classes in order of
  // specificity. One suggestion is made for every element of the current path,
  // though numeric elements are not carried to subsequent suggestions. For
  // example, for $base='page', http://www.example.com/node/1/edit would result
  // in the following suggestions and body classes:
  //
  // page__node              page-node
  // page__node__%           page-node-%
  // page__node__1           page-node-1
  // page__node__edit        page-node-edit

  $suggestions = array();
  $prefix = $base;
  foreach ($args as $arg) {
    // Remove slashes or null per SA-CORE-2009-003 and change - (hyphen) to _
    // (underscore).
    //
    // When we discover templates in @see drupal_find_theme_templates,
    // hyphens (-) are converted to underscores (_) before the theme hook
    // is registered. We do this because the hyphens used for delimiters
    // in hook suggestions cannot be used in the function names of the
    // associated preprocess functions. Any page templates designed to be used
    // on paths that contain a hyphen are also registered with these hyphens
    // converted to underscores so here we must convert any hyphens in path
    // arguments to underscores here before fetching theme hook suggestions
    // to ensure the templates are appropriately recognized.
    $arg = str_replace(array("/", "\\", "\0", '-'), array('', '', '', '_'), $arg);
    // The percent acts as a wildcard for numeric arguments since
    // asterisks are not valid filename characters on many filesystems.
    if (is_numeric($arg)) {
      $suggestions[] = $prefix . $delimiter . '%';
    }
    $suggestions[] = $prefix . $delimiter . $arg;
    if (!is_numeric($arg)) {
      $prefix .= $delimiter . $arg;
    }
  }
  if (drupal_is_front_page()) {
    // Front templates should be based on root only, not prefixed arguments.
    $suggestions[] = $base . $delimiter . 'front';
  }

  return $suggestions;
}

Have a look at the $delimter argument. The default is '__' for theme_hook_suggestions().


How to delete a large amount of nodes effeciently during cron? I implemented hook_cron() to delete nodes older than 30 days using node_delete function. Tracing the performance displays this:

  2015-07-06 21:28:49 Drupal watchdog
  ApCleanup::node_delete|/fpe/article||0||Node ID 423466 has been
  deleted [1.1173 secs]
  request_id="v-b8288e7a-2415-11e5-b14b-22000aeb06a5"

A single node deletion takes 1.1 sec. What is the most efficient way to delete the (2075546) nodes using hook_cron() and the node_delete_multiple function?

I would not recommend using Cron for this task.Since you have so many nodes it would always time out. Your better off using Drush and the Delete All module.
Or if you're fully purging all your nodes for instance I have written an SQL script before I can invoke with Drush which uses the sql truncate command to remove all data from Fields of a content type and then does a delete all from node and node_revisions for the given content type, and url aliases -- etc. Using SQL makes such a task take very little time for hundreds of thousands of nodes.
EDIT:
The Delete All admin UI has options for a quick delete that uses sql JOINs and not node_delete. See the admin form code: http://cgit.drupalcode.org/delete_all/tree/delete_all.module#n71
I suggest you install and try using the module.


Can you print single view fields in a block template file? I am new to drupal and I am wondering how to gain more control over a view block. Currently I am embedding my view block in my page by doing :

<?php print views_embed_view('news_overview', $display_id = 'block'); ?>

This works but if I want to style this further I have to go into my view and format it as content and add the html templating there which leaves me with a bit less control than I want.

I made a views-view--block.tpl.php file to try and style my view block a bit more but I am left wondering how to render single view fields here.

I tried doing this to for example render a body field:

<?php foreach($view->result as $object): ?>
    <?php print render($object->_field_data['nid']['entity']->body['und'][0]['value']); ?>
<?php endforeach; ?>

Ofcourse doing this for each field is a hassle and I was wondering if there is an easier way to output view fields inside my views-view--block.tpl.php template.

Cheers.

The first thing do not use that tpl file(views-view--block.tpl.php), this will alter all views of your current system. you can use views-view--news-overview.tpl.php this will alter your current views view only, there is many suggestions in views->advanced->theme:information. you can use appropriate tpl file.


Get all fields defined in a bundle In Drupal 7, to get all fields used in a content type, I use the following code.
$fields = field_info_instances('node', 'article');

What is the equivalent for Drupal 8?

EntityManager is deprecated moving forward.  The following can be used instead:
$entityFieldManager = \Drupal::service('entity_field.manager');
$fields = $entityFieldManager->getFieldDefinitions($entity_type, $bundle);

Whereas $entity_type can be 'node' and $bundle can be 'article'


How to remove 'By term' and 'View' tab being displayed at top of pages? On a Drupal 6 site, I have these annoying 'View' and 'By term' tabs being displayed on all node types. I am wondering how to remove/disable both of them?

'By term' seems to be generated by one of the views in Organic groups: posts_by_term. You should be able to disable it at admin/build/views. Here's the issue https://drupal.org/node/1635082.

The View tab should not be displayed if it's the only tab, for example for authenticated users who don't have permission to edit the node.

Removing the View and Edit tabs, should you want that, is a bit complicated because you still might need them in some situations. Here's a pretty thorough conversation about that: https://stackoverflow.com/questions/3530756/how-to-hide-edit-view-tabs.


How to stop a Views block from displaying to administrators, such as user/1? I created a view and put an access role of anonymous user. When I log in with normal user account I don't see it, but when I log in with my admin account I see the view.

I would like to not see it. Is there a way to stop it from displaying to admins?

BTW, I tried un-checking Bypass views access control in the permissions, but it didn't work.

Below is an answer to what I think this question is really about, i.e. "I would like to not see it. Is there a way to stop it from displaying to admins?". And to make the challenge a bit tougher, not for a user with role "Administrator", but assuming "... you are talking of the user with ID equal to 1 ...".

My short answer to it is "Yes you can" ... read on for more details ...

Part 1: Rules block visibility

You should be able to get this to work using the Rules block visibility module. Here is a quote from its project page:

  The Rules block visibility module allows Rules components to be used to control block visibility. This provides Drupal administrators and developers extreme flexibility in controlling when blocks should be displayed on their websites, in addition to the default visibility options provided by Drupal.

  The general idea is that if you can do it with Rules, you can use it to control block visibility, so the possibilities are limitless:

  Need to show a block only for users registered more than a month ago?
  Perhaps you have a block that must be shown only between 8am-5pm on weekdays?
  What about displaying or hiding a block based on current weather conditions?

  All of this can be done by using Rules block visibility.

With that, and as per the "if you can do it with Rules, you can use it to control block visibility" above, you've reduced your question to making Rules intercept the actual user who's using the site, i.e. if it is YES or NO (a boolean, right?) the user with uid = 1.

Part 2: Create an appropriate Rules Component

The Rules block visibility module doesn't have a lot of documentation, except in the README.txt that comes with this module. Here is what the crucial part of it is (to get the idea):

  Configuration is done on a per-block basis. To control a block
  visibility using a rule component, go to the block settings page,
  scroll down to the "Rules" tab, and select the Rules component that
  you want to use.

  Notice that to be able to be used by this module, a Rules component
  must be constructed in a very specific way. See the next section for
  more information.

This module comes with 2 sample Rules Components, that should help to understand the KeepItSuperSimple concept behind it.

By looking at these samples, I was able to create another Rules Component which looks like so:

{ "rules_block_visibility_hide_block_for_user_1" : {
    "LABEL" : "Hide block for user 1",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : {
      "module" : { "label" : "Module", "type" : "text" },
      "delta" : { "label" : "Delta", "type" : "text" },
      "result" : { "label" : "Result", "type" : "boolean", "parameter" : false }
    },
    "IF" : [
      { "NOT data_is" : { "data" : [ "site:current-user:uid" ], "value" : "1" } }
    ],
    "DO" : [ { "data_set" : { "data" : [ "result" ], "value" : "1" } } ],
    "PROVIDES VARIABLES" : [ "result" ]
  }
}

You should be able to import this rule in your own environment.

What this Rules Component does is "only" return a boolean (1 or 0), based on the condition if the user's uid is YES or NO equal to 1.

With that, we're coming close to an actual answer to your question. But note that, as a variation, you could also have used a rules condition like "does this user yes or no have a role like administrator".

Part 3:

Head over to the "Block" settings for the block you want to hide for the user with uid = 1. At the bottom of it's settings, within the typical "Visibility settings", there is now (after you enabled the Rules block visibility module as in Part 1) an extra tab labeled "Rules". Using that tab will allow you to select a "Rules Component" that will do what's documented below that selection list field, ie: "Show this block only if the selected rule returns a positive value. Important: to be listed here, a block visibility rule must have specific parameters and return values.".

And guess what, in my case I just selected my Rules Component from Part 2

Notes:

It doesn't matter what type of block it is (created by a view, or something else), it works in all cases.
This answer applies to D7.


Passing form value into batch process I have a form that is used to trigger a bulk operation and add a node for each of the currently registered users on the site. This is all working well, but I'd like to pass form data from BulkAddForm.php to the batch operation in BulkAddNode.php

If is were to setup a variable called $year in BulkAddForm which contained form state. How would I then use it in a line like this...

'title' => 'Perf-plan-' . $year . '-' . $user->get('field_user_employeeid')->value,

BulkAddForm.php

<?php
 namespace Drupal\create_perf_plan_for_new_year\Form;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
/**
 * Class BulkAddForm.
 *
 * @package Drupal\create_perf_plan_for_new_year\Form
 */
class BulkAddForm extends FormBase {
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'bulk_add_form';
  }
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['perfPlanYear'] = array(
      '#type' => 'textfield',
      '#title' => 'Year Tag (1819 for instance)',
    );
    $form['bulk_add'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Create new Performance Plans'),
    );
    return $form;
  }
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $uids = \Drupal::entityQuery('user')
      //->condition('type', 'batch')
      ->sort('created', 'ASC')
      ->execute();
    $batch = array(
      'title' => t('Bulk Add happening within the Bulk Add Form file...'),
      'operations' => array(
        array(
          '\Drupal\create_perf_plan_for_new_year\BulkAddNode::bulkAdd',
          array($uids)
        ),
      ),
      'finished' => '\Drupal\create_perf_plan_for_new_year\BulkAddNode::bulkAddFinishedCallback',
    );
    batch_set($batch);
  }
}

BulkAddNode.php

<?php
namespace Drupal\create_perf_plan_for_new_year;
use Drupal\node\Entity\Node;
use Drupal\user\Entity\User;
use Drupal\Core\Url;

class BulkAddNode {

    public static function bulkAdd($uids, &$context){
    $message = 'Bulk add happening in functional file...';
    foreach ($uids as $uid) {
        $user = \Drupal\user\Entity\User::load($uid);
        \Drupal\node\Entity\Node::create([
            'type' => 'perf_plan',
            'title' => 'Perf-plan-' . '1718' . '-' . $user->get('field_user_employeeid')->value,
            'uid' => $user->id(),
            'field_employee_uid' => $user->id(),
            //'field_supervisor_uid' => $user->get('field_supervisor')->first()->getValue()['target_id'], //Brilliant means of getting entity reference UID from User. SM
            //'field_director_uid' => $user->get('field_director')->first()->getValue()['target_id'],
          ])->save();
    }
    $context['message'] = $message;
  }

function bulkAddFinishedCallback($success, $operations) {
    if ($success) {
      $message = 'Performance plan added.';
    }
    else {
      $message = t('Encountered an error during bulk performance plan creation.');
    }
    drupal_set_message($message);
  }
}

You can pass variables to the batch process by doing the following...

     $year = "2018";
     $batch = array(
          'title' => t('Bulk Add happening within the Bulk Add Form file...'),
          'operations' => array(
            array(
              '\Drupal\create_perf_plan_for_new_year\BulkAddNode::bulkAdd',
              array($uids, $year)
            ),
          ),
          'finished' => '\Drupal\create_perf_plan_for_new_year\BulkAddNode::bulkAddFinishedCallback',
        );

Year in this case can obviously be anything... a piece of $form_state for instance also works.

You could then change

public static function bulkAdd($uids, $year, &$context){
    $message = 'Bulk add happening in functional file...';
    foreach ($uids as $uid) {
        $user = \Drupal\user\Entity\User::load($uid);
        \Drupal\node\Entity\Node::create([
            'type' => 'perf_plan',
            'title' => 'Perf-plan-' . $year . '-' . $user->get('field_user_employeeid')->value,
            'uid' => $user->id(),
            'field_employee_uid' => $user->id(),
            //'field_supervisor_uid' => $user->get('field_supervisor')->first()->getValue()['target_id'], //Brilliant means of getting entity reference UID from User. SM
            //'field_director_uid' => $user->get('field_director')->first()->getValue()['target_id'],
          ])->save();
    }
    $context['message'] = $message;
  }

Hope this helps. It took me a while to figure out where in the batch array structure this needed to be placed. I didn't find the docs particularly helpful.


How to secure ajax on automatically save field data My custom module make ajax request on _node_edit form after input changed by user, and menu callback save this field's data (only this field, not all node object). Menu item is as "field-save/NID/FIELD_NAME", and the input val is on $_POST['field_data']. Menu item have own permission per role. Additionally each user have own randomly generated secure string and it is on the same ajax $_POST['secure_phrase']. Menu callback checking for permission per role and this secure string per user, if have access going forward to save field data.

The question: Is this enough security to prevent for unauthorised access to save field through this ajax request?

edit:
additional for this on "access_callback" i have

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
  // checking permissions here
}

It seems pretty secure. Also check the content type permissions for the role ;)


How do I set the node path with a contextual filter? I'm creating a simple job board for my company in Drupal 7 w/ Views.  I have a view which creates a page that lists all available jobs.  Within each job is a truncated description which I have set to trim and display a "Read More" link which goes to the details of the job posting.

To generate the "Read More" link, I am using a contextual filter which pulls the [nid] and in the 'body' section I have the "Read More" link set to node/[nid].  This works exactly the way I need it to.

The issue I'm having is that I have created another page within the view to display the full job posting.  And instead of going to www.mydomain.com/node/3166, I want it to go to something like www.mydomain.com/jobs/current/posting/3166.  (I'd like to use the nid as some jobs might have the same title).

I go into this view and set the path to 'node/%' and the view shows up formatted and everything when details are clicked, however, setting this bombs out ALL of my other content within the site.  So I tried setting the path to something like 'jobs/current/posting/%' and I just can't get it to work.

Does anyone know what I'm doing wrong and/or have a solution or workaround??  TIA

First of all you don't need Contextual filter in your first case where you are generating link as "node/[nid]" , what you need is replacement pattern. Todo this you can simply add nid to fields list and place above read more link and use the pattern.
Change read more link to "jobs/current/posting/[nid]"

Regarding what you are trying to solve

You cannot have a view with path "node/%" since it's already taken by node module to render node pages. It will conflict with node module and as you said "bombs out ALL of my other content"
In your view set path as 'jobs/current/posting/%'
Add a contextual filter nid and set provide default value to content id from URL as shown below.


Search Api Autocomplete doesnt filter by language We're using Search API Autocomplete with Search API 7.x-1.9 on a site set up with Solr (Websolr) serving nodes in both English and German.

I'm looking to be able to filter the results by ss_search_api_language field which is presently not happening and as such i get autocomplete results for all both languages.

What would be the correct approach to deal with this?

This issue has been fixed by fons vandamme via the drupal module issue tracker

function filter_by_language_search_api_query_alter(SearchApiQueryInterface $query) {
  //if query is of type search_api_autocomplete we will add our extra language filter
  if (strpos($query->getOption('search id'), 'search_api_autocomplete:') !== false) {
      dsm($query->getOption('search id'));

      global $language;

      $filter = $query->createFilter('AND');
      $filter->condition('language', $language->language, '==');
      $query->filter($filter);

  }
}

Make sure the language of your nodes are in the index.

https://www.drupal.org/node/2166113


How to update image title and alt tags I am using Drupal Commerce.
Images are in product entities.
I have imported my products and nodes with feeds, but now I am working on SEO of my website, I have realised that my 'title' and 'alt' tags are empty.
I am looking for a process to update these tags with the image title :

With Feeds I haven't found the way to update these tags ?
I tried (How to bulk update image alt and title?) with VBO but it doesn't work.

This issue sounds common and trivial but I can't find a solution. Am I missing something ? Is there an other way to automatically replace title and alt image tags with image field title ?

Thank you for your help

The way I deal with this issue is to use the ImageField Tokens module:

  The ImageField Tokens module extends the default functionality of
  Image fields adding the ability to specify default values and use node
  tokens in the Alt and Title text.

The module Token is required. After you install and enable the modules, you configure its settings in the field properties for each individual content type.


Date Range filtering using Google Search Appliance crashing I'm working with the Google Search Appliance and corresponding drupal module. I've followed the user guide linked on the project page (also here) on creating filters. I was hoping to create a date range filter, however, I'm a bit stumped on how to filter on content types that have date ranges themselves.

For example, if I had a content type of person who had a year range of 1900 - 1970 (IE, years they lived). I figured I would create a metadata field that would have each date listed, so that google would know each year the content type covers. The filter part is the part where I'm having trouble.

In my custom module, i'm trying to set my $query['gsa_query_params']['requiredfields'] to be a range of dates in the form of "1900|1901|1902". That does work, but if the range is too big (around 30 years), the search fails. I'm lost.

So the drupal module uses curl to query the google search appliance, which means if your url is too long, you may run into issues.

It would be better to send a range to the Google search appliance by altering the $query['gsa_query_params'], ether by using the required-fields or partial-fields.

However, google doesn't currently support ranges to be sent via these options. Hopefully they'll add that functionality, but if you can't wait indefinitely for them to add the functionality, you can get a bit hacky and get it to work.

So, the Google Search Appliance has a flag, "inmeta" which does allow you to create a integer range. The catch here is it can only be used in a query field. IE a search for

  "John Doe AND inmeta:1901-1940"

What you could do though is use the GSA Drupal module.

hook_google_appliance_query_alter (where your altering your queries to create your other filters) to add to your q string "AND inmeta:[range]". The issue here is that when you use this, drupal will display the full q string, with the inmeta field showing. Which might look strange for your users. You could save a copy of the q string before adding the range to your $query variable. Then, before displaying the page, but after the query has been executed, switch the query string back out.


How to split content over different regions... views? I have a client who wants to allow some editorial staff to create and edit 'main pages' on their site. These are things like 'about us', 'our clients', 'breaking news' and so on; they want these 'main pages' to follow a house style (one main image, relevant links here, block quote there, content in the middle, etc.)

The site is built with Drupal 7.

I'm thinking that the way to go is probably using a custom content type, 'main_article' and then using views to display various fields from that content type in the relevant blocks - so, for example, having a 'main content' block that sits in the content region and displays the title and main content, 'picture' and 'links' blocks that both go in the left column, and 'citation' and 'blah' blocks over in the right column.

I guess I would use the 'Content: NID' contextual filter to make sure that I only get content from the relevant 'main_article'.

This seems like a standard enough design issue: Am I going about it in the right way?
Is there a better solution?  (I've seen similar questions here and elsewhere that led me to follow this way of doing it.)
How would I go about getting the 'main_article' content type to put a link in the main navigation menu?
Using the menu option in the content creation page would link to the default content, not the view (if you see what I mean). Could it be done using a field?
If the user creates a URL Path for the content they create using this content type, that's going to break the 'content: NID' contextual filter. Is there a way of 'contextual filtering' on the URL (which should then work for standard node URLs and for 'nice' URL paths)?

An simple solution is to use the Panels module and Page Manager from ctools module to override the default node page for your content type.  That way you also do not have to worry about menus, sitemaps etc.

The downside is that you cannot easily use the blocks defined in the template to position parts of the nodes content.