how to exclude current node from a view inside a node commerce kickstart I know variations of this have been asked left and right but I can't get this to work.

I have a Commerce Kickstart Product Display (shopping cart form, basically a node).

Inside this content type is a display field which uses ViewField to insert a View inside the form. This View is a list of related products (nodes in the same category). I pass the category of the current node as a token %1 to the View and it works great.

However, I'd like to further exclude the current node (ie. the product being displayed) from this Related Products view.

I tried adding a second Contextual Filter:

Indexed Content: Node ID
Provide Default Argument: Content ID From URL

and then checking the 'Exclude' box in the More section.

And this does nothing. The current node still displays in the Related Products View.

NOTES:
1. FWIW: This View is of Type: 'Product Display' (from Commerce) as opposed to 'Content' or 'Message')

There is no default argument for 'Node ID'. Only 'Indexed Content: Node ID'. Probably because of the type of View (I cloned an existing view in Commerce Kickstart as a template.)

Any ideas?

Why don't you rather just pass the product display node id as a second parameter in your view field (you are allowed to use a comma separated list of arguments), and then don't bother with providing a default argument at all. The second argument to pass is [node:nid]


How can I dynamically add drupal behaviors to a form from php using ajax? I am creating a form which dynamically changes based on the value of a select element.  What happens is this:

The user selects a value from the select element
The select element uses Drupal's ajax methods to reload the form, now with some new elements for further configuration
Some of the new elements need to be turned into jQuery widgets.

Now, the obvious solution here is to use behaviors to run the widget initialization code.  The issue is that I don't know ahead of time which elements need to have what code run on them.  I will only know that at the time the ajax portion of the form loads.

Currently, my solution is to have a very short JavaScript file which is solely responsible for adding new behaviors which in turn run the jQuery UI code that I need.

An alternate solution is to pre-load all of the possible configuration elements and inject all of the behaviors ahead of time.  For various reasons this isn't a good idea, not least because I rather like lazy loading.

My question is: is there some way to attach behaviors in php through Drupal's ajax mechanism, like there is a way to modify the settings?

Yes you can attach Drupal Behaviors to newly added elements (DOM nodes):

You can check ahah.js (in Drupal.ahah.prototype.success):

// Attach all javascript behaviors to the new content, if it was successfully
// added to the page, this if statement allows #ahah[wrapper] to be optional.
if (new_content.parents('html').length > 0) {
  Drupal.attachBehaviors(new_content);
}

Or if your script creates the elements (answer on stackoverflow about drupal-behaviours):

var newNodes = $('Hello World').appendTo('#someDiv');
Drupal.attachBehaviors(newNodes);


Optimized way to use media queries I'm looking for the best way to use media queries within a drupal theme (based on Zen 5)

The options I've found are :

Defining media queries in the info file eg :

stylesheets[all][] = styles/base.css
stylesheets[all and (min-width: 480px)][] = styles/480up.css
stylesheets[all and (min-width: 720px)][] = styles/720up.css
stylesheets[all and (min-width: 960px)][] = styles/960up.css

Include all the css file and wrap all definitions within the media queries in the files
Use base.css and use media queries at the end of this file to import others stylesheets.

Of theses three options, which is the lightest? Is there a fourth one?

The second option would be better, because of aggregation.

For the first option, if you turn on aggregation on your site, the files will be bundled by media query. So, in your case, you would have at least 4 bundles, so 4 requests to fetch your site CSS files.

For the 3rd option, the browser will request the imported CSS files seperately, so you lose the benfit of aggregation completely.

If you put the media queries inside the CSS files, they will be aggregated together, resulting in only one bundle. This is better for performance, especially for mobile devices.


Entity vs taxonomy vs content type? I am setting a website up that will house multiple language schools, so I am mainly dealing with:

Individual language schools
Language courses

I set up a content type called ‘Schools’ and have fields on this that are unique to a specific school, example:

School Name
School Location
Tel no and contact details
Description of school

I then used entities for these things that are also unique to a school but there are quite a few of them, so I thought I’d be better with entities, then use inline reference entity fields on the school nodes (is this correct?):

Types of accommodation
Activities
Facilities
Image Gallery

Now I have come onto adding courses, there is generally a theme for these at the top level such as: ‘Intensive English’ then each school has various classes, so you mght have ‘Intensive English’ MORNING or ‘Intensive English’ EVENING. Now I don’t want to create taxonomies for this classes as I’ll have URLs that don’t have anything on them, I’d have a table with the various classes in it. But the whole website needs to be searchable.

My question is, what do I need to do for courses? I used entities but now can’t create a view that shows the nodes referencing the schools nodes and place it on the taxonomy parent: General English, Intensive English etc. Anyone got an pointers on what I should do and if I have set this up correctly?

I am struggling to create a view that shows a course page and then the schools that offer it, despite creating a reference to it, as in the image. Tried everything with contextual and relationships.

You're right, something that is a 'descriptor' or category is best left as Taxonomy (i.e. Time > Morning/Afternoon/Evening) where they are used to enrich the meaning of data.

  Now I don’t want to create taxonomies for this classes as I’ll have URLs that don’t have anything on them

If access to taxonomy paths is a concern, you can install the Rabbit Hole module to disable access to it while preserving the functionality of taxonomy behind the scenes.

You can also use other modules like Taxonomy Views Integrator to 'change' the way taxonomy paths behave. In this modules case, you can display a View on these paths instead of the default page callback for taxonomy. The View can be anything you'd like.

Otherwise, if you attempt to create a custom table to store this data, you will need to use the appropriate hooks in the Views API to describe the table and it's data, and how it relates - which can be a lot of work. In the end, it sounds like you'd wind up duplicating taxonomy current functionality.


How can I specify the URL alias when importing nodes into Drupal 7 (with the Feeds module)? I'm importing a site into Drupal 7, using the Feeds module.  I don't see any way to specify the URL alias for each node (which I want to control on most every page).  How can I do this?  (If the Feeds module cannot do it, is there a way to do it in bulk after the import?)

Update: in case it's not clear, I want to have a column in my CSV that lists the URL alias that I want for a particular node.  I don't want the URL automatically generated.  I want completely control over the URLs, without having to manually specify them in the Drupal admin UI.

Try the Pathauto module to do this. I found it helpful for auto-aliasing URLs in bulk, and it is customizable... it works pretty well if you use taxonomy to improve work site flow.


How to get the label values for list fields in Twig? I'm trying to fetch the label of the list and display it on the twig template.

Using node.field_list.value outputs the key value. I tried using node.field_list.label but it returns empty. I tried using node.field_list.title, node.field_list.0.label or node.field_list[0]['#markup'] but it still returns empty on the twig template

There are a few ways:

It calls List allowed values and it stores in the field configuration.

When field cardinality is 1

  {% set list_value = node.filter_list.value %}
  {{ node.filter_list.getSetting('allowed_values')[list_value] }}

When field cardinality is more than 1

  {% set allowed_values = node.filter_list.getSetting('allowed_values') %}
  {% set list_values = node.filter_list.getValue() %}
  {% for list_value in list_values %}

      {{ allowed_values[list_value['value']] }}

  {% endfor %}

In case when your template is node.html.twig you can render it based on field formatter in your view mode.

  {{ content.filter_list }}


Equivalent method or "body onload" First, I have tried for several hours to weed through the various search results of the keywords above. I've found several things that seem to answer this but they're for Drupal 7; one of those was posted on 2012 and I am pretty sure things are gosh darn different now.
I am not a programmer, nor a web dev professional; I am just someone trying to update a very old site that worked fine but that needs to be re-freshen. I have some experience as a content manager with Drupal 6, but I have never got into coding, building modules, or editing template files. I am not afraid to copy a file, open it in an editor, change this or that, cut or paste, but I don't see myself being able to build a module to do this.
Maybe there's no way to do this "easily."
I want to replicate a Google map with a custom search feature and some other tweaks. It works nicely in the existing site and it is basically 3 parts: a <script>code here</script> in <head>, some HTML and script in the body,  and the following markup for <body>.
<body onload="load(); curvycurvy()" onunload="GUnload()">

All I am hoping to do is properly add this code on my new Drupal 8 front page.  I've used the Asset Injector module to add the bulk of the script to <head> and used <front> to restrict it to the front page. I have chosen PHP for the content and it seems to retain the script.
Is there a way to add this code above into the body? Failing that, is there a way to provide similar functionality?
I was hoping that the Asset Injector has some tools like, "Add to the Body Tag" or such, that would have been exactly what I need.

This is fairly easy and covered well in the Javascript API section of the drupal docs.

Effectively you want a Javascript file that creates a Drupal behavior (this is automatically fired when the document is ready). Inside the behavior, just call curvycurvy();.

https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview

So, for starters...

Drupal.behaviors.initCurvy = {
  attach: function (context, settings) {
    curvycurvy();
  }
};


Add element inside main menu block, but outside navigation I need to add an element somewhere within, or directly before/after, the main menu block. For example, the generated HTML should be something like this:

            About

                General Info

Video

I am currently trying hook_block_view_alter() and have tried multiple variations of something like this:

function theme_block_view_alter(&$data, $block) {
  if ($block->delta == 'main-menu'
    && $block->region == 'menu') {
    $data['content'][] = array(
      '#markup' => '
Close Mobile Menu
'
    );
  }
}

which is the closest I have come.  This adds the div within ul.menu (top level) after the last li element; that won't work.

I can't seem to find a theming function for the menu as a whole, just theme_menu_links().  I see the theme wrapper menu_tree__main_menu within $data in hook_block_view_alter(), but I don't see a file or function that resembles that.

I'm aware that there may be a much better solution that I'm just not thinking of, so I'll state the final goal:

Absolute positioned menu. (I can work with #main-navigation being absolute and the element coming after it or with ul.menu being positioned, and the element coming after it.)
A link that follows the menu in markup, but is outside of the absolute positioned menu, so that I can position relative to window, not the ul.

Thanks!

To accomplish all your goals, you need to implement these three functions:

hook_preprocess_block()
theme_menu_tree()
theme_menu_link()

Create one template file for the block with your menu.

template.php

/**
 * Implements hook__preprocess_block().
 */
function YOURTHEME_preprocess_block(&$variables, $hook) {
  // allow to use block templates depend on delta
  // example: delta = main-menu ; template file: block--main-menu.tpl.php
 if ($variables['block']->delta == 'main-menu') {
    $variables['theme_hook_suggestions'][] = 'block__' . str_replace('-', '_', $variables['block']->delta);
 }
}

/**
 * Main menu
 * Implements theme__menu_tree().
 */
function YOURTHEME_menu_tree__main_menu($variables) {
    global $level;
    $div = ($level == 1) ? '
 ... some div next to the main ul ...
' : '';
    $ul = '
' . $variables['tree'] . '
' . $div;
    return $ul;
}

/**
 * Main menu
 * Implements theme__menu_link().
 */
function YOURTHEME_menu_link__main_menu($variables) {

  $element = $variables['element'];
  $title = $element['#title'];
  $sub_menu = '';

  // global menu level variable.
  // within theme_menu_tree() at first level has always value = 1
  // but not here, that's why $depth will have to be defined separately
  global $level;
  $level = $element['#original_link']['depth'];

  // if you will need $depth, it must be defined separately
  // $depth = $element['#original_link']['depth'];

  // submenu
  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }

  // link output
  $output = l($title, $element['#href'], $element['#localized_options']);

  // if link class is active, make li class as active too
  if(strpos($output,"active")>0){
    $element['#attributes']['class'][] = "active";
  }

  $attr = drupal_attributes($element['#attributes']);
  return  '
' . $output .$sub_menu . "
\n";
}

block--main-menu.tpl.php

<?php
/**
 * @file
 * theme's implementation to display a block with the main menu.
 */
?>

        <?php print $content; ?>

 ... some div next to the main navigation div ...

Results


restrict user to libarary tab in media file selector in media module I want use media file selector  as image field in content type . media module provides it to select and upload image by popup, but I dont want user can upload image ,I just want only user can select file from library tab in media file selector.
any body know how can I achieve this job?

To prevent user(s) from uploading files, remove the following permission from their role (admin/people/permissions)

  edit media

For the role to still be able to access the library of media that has already been uploaded, ensure that they still have the permission

  Import media files from the local filesystem


Add CSS class to  element using webform and template file I have an existing webform in Drupal 7 which I am trying to theme.
So far I managed to add CSS classes, placeholders, prefix, suffix,.. to form elements (fields) but not to the actual <form>-tag?

I tried this:

$form['#attributes']['class'][] = 'form-horizontal';`

But that didn't change anything to the output.

edit: I have found that putting var_dump($form['#attributes']); displays the array below the form-tag. Does that mean that you cannot alter the root element inside a template file (webform-form-8.tpl.php) and that I should implement the hook in template.php?

I believe your edit is correct. You should add the class in a preprocessor function within template.php.

A similar question and answer can be found here.


Drupal Views Exposed filter ( Taxonomy ) I have 3 fields ( Exposed filter ) 1 Country 2 State 3 City

When a respective Country is selected in the 1st field, I want the second filter ( Dropdown or autocompete ) to display states of the country selected in the 1st field & when this is done based on the state selection , I want the 3rd field to show only the cities belonging to the state selected in the second field.

How can this be done ? any help ?

If you have arranged your taxonomy in a hierarchical manner, then you can use the Hierarchical Select module:

https://www.drupal.org/project/hierarchical_select


disabled="disabled" on a checkbox entity field I can't seem to figure out how to make checkbox field on my entity display as disabled in the admin form area. Looked in Drupal 8s "documentation" but couldn't seem to find anything on it.

I tried variations on the code below but nothing seemed to work. Any help is appreciated. Thank you.

$fields['some_field'] = BaseFieldDefinition::create('boolean')
 ->setLabel(t('Some Field'))
 ->setDescription(t('A Field description'))
 ->setReadOnly(TRUE)
 ->setRevisionable(FALSE)
 ->setDefaultValue(FALSE)
 ->setDisplayOptions('form', [
   'type' => 'boolean_checkbox',
   'attributes' => array(
    'disabled' => true,
   ),
   'weight' => 0,
]);

The BooleanCheckboxWidget has no settings for HTML attributes. You either have to create your own Widget or use hook_field_widget_WIDGET_TYPE_form_alter to add the disabled attribute.

Not tested personally, but you might also take a look at the Read-only Field Widget, could save you some coding: setDisplayOptions('form', ['type' => 'readonly_field_widget', ...])


D2D file migration cannot processes a number of rows? In my Drupal 6 site I have 147490 files in the database.  On my Drupal 7 site I am using D2D migrate module to import them.  The number of Items it sees is exactly the same, 147490.  However, it will not processes 5683 of them.  112229 import successfully and 29578 fail (because the file no longer exists on the server, that's fine).  When re-running the migration, it will not processes the remaining 5683.

Here is my migration class:

  $file_arguments = $common_arguments + array(
    'machine_name' => 'Files',
    'description' => t('Migration of files from Drupal 6'),
    'user_migration' => 'User',
    'default_uid' => 1,
    'source_dir' => 'http://lcl.legacy-d6.com/sites/default/files',
    'destination_dir' => 'public://',
  );

  Migration::registerMigration('Files', $file_arguments['machine_name'], $file_arguments);

I am then extending the class with an include: file_migration.inc

class Files extends DrupalFile6Migration {
  public function __construct(array $arguemnts) {
    parent::__construct($arguemnts);

  }

  public function prepareRow($row) {
    if (parent::prepareRow($row) === FALSE) {
      return FALSE;
    }

    $filepath  = $row->filepath;
    $new_filepath = str_replace('/var/www/html/liv-dir/production/', '', $filepath);
    $new_filepath = str_replace('/var/www/html/lcl.legacy-d6.com/htdocs/', '', $new_filepath);
    $row->filepath = $new_filepath;

    return TRUE;
  }

}

EDIT: I was able to create a snippet that finds all of the missing Ids however I was not able to figure out why they are not being processed.

    set_time_limit(0);
    $unprocessed_ids = array();
    db_set_active('legacy');
    $get_fids_query = Database::getConnection('legacy')->select('files', 'fi');
    $get_fids_query->fields('fi', array('fid'));
    $result = $get_fids_query->execute();
    while ($fid = $result->fetchField()) {
      db_set_active();
      $check_migration_query = Database::getConnection('default')->select('migrate_map_files', 'mfi');
      $check_migration_query->fields('mfi', array('sourceid1'));
      $check_migration_query->condition('sourceid1', $fid, '=');
      $check_migration_result = $check_migration_query->execute();
      $check_migration = $check_migration_result->fetchField();
      if ($check_migration === FALSE || is_null($check_migration) || !isset($check_migration)) {
        $unprocessed_ids[] = $fid;
      }
      db_set_active('legacy');
    }
  }

UPDATE: The only fix I could find that actually worked was waiting for the migration to run its course and then rollback a small number of rows, and then run through the migration again with --update flag set.  Depending on the envioronment I was running on (local vs pantheon) I would have to do this between 5-20 times.

I still want to know why this was happening.

I just faced the same issue, and have a suspicion what the cause may be, though have not tested it.

I ran a migration of files in manual batches, e.g.

drush migrate-import MyMigration --limit="100 items"

several times. After the last batch (for which I did not specify an item limit, i.e. it should have imported all remaining unprocessed items), migrate-status still showed almost 900 unprocessed items. All calls thereafter to migrate-import would process 0 items, even with the --update flag -- which I thought should have either imported or updated (accordingly) ALL items...

Just as you did, I then queried for the source IDs it would not process. Upon inspection I noticed that large sets of them had the same exact timestamp (specifically, file_managed.timestamp column in the database). I recalled that Migrate can use a specified field to store a highwater mark for each migration, such that future import runs will only process items whose value of that field is greater than the stored highwater mark from previous runs. So for files, the timestamp value is used by default (per Migrate D2D implementation -- see DrupalFile7Migration::__construct()), and the query is ordered by timestamp ASC to cooperate with this.

I realized that the items it would not process were definitely older than the stored highwater timestamp (which is that of the newest item imported). Why then did Migrate not process those in an earlier batch, based on the query's order-by? Well... if many of my files had the same exact timestamp, the results of the query were not guaranteed to be in the same order across different runs. So if I was working with a limit of 100 items per run, but the results were not consistently ordered, it's possible some items never ended up falling within the batch (range of results) that was actually being imported at the time.

I'm not entirely sure if this could account for nearly 900 unprocessed images, but it's a thought.

Workaround

You can import items regardless of their status vs. the highwater mark by using the --idlist argument. So since you've queried to find the source IDs that won't process, just pass them as a comma-delimited string and I think it should work no matter what. Example:

drush migrate-import MyMigration --idlist="538,2891,485"

Actual fix? (untested)

If my suspicion is correct, then probably the solution is to order by not only timestamp, but additionally by fid, which is guaranteed unique, and thus the results order will be exactly the same every time. In your migration subclass, override query() and after calling the parent implementation, add $query->orderBy('fid', 'ASC'). This sets secondary ordering.


Automatically update Drupal core/modules for a large number of sites (with Drush)? I'm the administrator of a lot of Drupal websites on different hosting providers.

Some have drush; others don't (and can't: like shared hosting).

Every time there is a Core upgrade, I spend 1 or 2 hours updating everything (I make a backup of every website before an upgrade).

Updating sites with Drush is simple, but I need to do it for every website, like :

drush @dev up
drush @othersite up
and wait... wait... wait...

How can I automatically update Core (and modules) on:

all my drush sites ? (I think : cron with bash script)
all my non-drush sites ?

Is this safe, or do you not recommend it?

What I would suggest, is to store all your Drupal sites in GIT repositories. With a separate branch / repo for Core and as many as necessary for /sites/*

Then you can easily do updates to cores by a simple pull. For shared hosting, pull locally, then sync by lftp to your distant hosts.


Add a relationship to logged in user, not content author, on content view? I want to filter my content view by a field on the logged in user (the content type has that same field). I could implement hook_query_alter and add add a where condition with the field from $global user, but is there a way to do this out of the box though the UI?

There is no way to accomplish this via UI. At least not if the User field may contain multiple values.

In the example below 'field_test' is a List(text) field w/ select widget (unlimited values allowed for user account). When the same field is added to Content type - I set it to allow for single values.

The code will take in consideration multiple values from User field and add WHERE  clause to the View that shows all nodes of a Content type.

WHERE clause filters out all nodes that have 'field_test' set to anything other than what currently logged in user has set in 'field_test' on their own account.

/**
* Implements hook_views_query_alter().
*/
function MYMODULE_views_query_alter(&$view, &$query) {
  // 'test_related_field' -> view's machine_name
  if ($view->name == 'test_related_field') {
    global $user;
    $user = user_load($user->uid);

    // 'field_test' -> field that is shared between user accounts ans content type
    $user_field = field_get_items('user', $user, 'field_test');
    if($user_field) {
        $query->ensure_table("field_data_field_test");
        // create query that processes multiple values of User 'field_test'
        $db_or = db_or();
        foreach ($user_field as $item){
            $db_or->condition('field_data_field_test.field_test_value', $item, 'IN');
        }
        $query->add_where('test_field_group', $db_or);
    }
    // use dpm() to see added WHERE clause
    //dpm($query);
  }
}

UPDATE:
If User field and Content Type field are allowed to have only single values then you can use UI for filtering view's results.

add shared field as Contextual Filter
Provide Default value for the field -> select PHP Code
enter the following code in the box

global $user;
$user_fields = user_load($user->uid);
$test_field = $user_fields->field_test['und'][0]['value'];
return $test_field;


Render a view in a given language in a custom command I have written a Drupal Console command that creates a huge batch of HTML snippets. This is done by rendering a view programmatically (as in this StackExchange answer)

The task

Now I have to create these snippets in several languages.

This works

If I call the view in my browser I can easily chose the language with the respective path prefix:

http://www.example.com/de/path/to/the/view (german version)

http://www.example.com/en/path/to/the/view (english version)

This does not work

If I try to render the very same view from a Drupal Console command I am not able to set the target language. The rendered HTML is always in the default language.

At first I thought passing the langcode in the view() method should suffice:

// Now render the node as HTML
$viewBuilder = $this->entityTypeManager->getViewBuilder('node');
$build       = $viewBuilder->view($node, 'full', $langcode);
$html        = $this->renderer->renderPlain($build);

Then I tried setConfigOverrideLanguage():

$this->languageManager->setConfigOverrideLanguage($language);

// … render the view here …

$this->languageManager->setConfigOverrideLanguage($originalLanguage);

But this did not work either. So it tried:

$this->configFactory->getEditable('system.site')->set('langcode', $langcode)->save();

// … render the view here …

$this->configFactory->getEditable('system.site')->set('langcode', $originalLangcode)->save();

But I did not succeed. I even tried using a custom LanguageNegotiator, but I ran into a fatal error due to the fact that the service 'language_manager' does not implement the ConfigurableLanguageManagerInterface, so it is missing the setNegotiator() and getNegotiator() methods.

Once again I am totally stuck and I don't know what I am missing (most likely just a tiny bit). How in the world is it possible to change the language of my rendered HTML???

Edit 2017-01-05:

I have to admit I am quite desperate atm. I even tried everything I ruled out above again. Guess what, it still does not work. Any ideas? I am so shure that I am missing only a tiny piece. But I don't have any idea where to search for :(

Edit 2017-01-17:

Obviously the console command is not aware of (parts of) the context, even if I set the language. Just to get it done I am considering putting together a request object which I would then have been handled by the kernel. If this should turn out to be too complicated I could still curl the respective pages, but I have a feeling that there should be another way of doing this.

Edit 2017-03-14:

First of all there there has to be a translation (even if the node data is in no way language specific). If you want the complete context you have to use the Kernel's handle method with a sub request.

You should call:

Drupal::service("entity_field.manager")->clearCachedFieldDefinitions();

after language changes.


Confirm delete via AJAX How can I have a JS confirmation button pop-up when a user clicks a button and then fire the #ajax defined for that button?

Right now, I have this button at the end of my form:

    //add an update button to the end of every row
    $form[$row_name][sizeof($data['columns']) + 1] = array (
        '#type' => 'button',
        '#value' => t('Delete Row'),
        '#name' => $row . '-_udr_delete_data',
        '#prefix' => "",
        '#suffix' => "	",
        '#ajax' => array (
            'callback' => '_udr_ajax_handler',
            'progress' => FALSE,
         ),
        '#weight' => 1001,
    );
  }
  $form['table_end'] = array(
      '#prefix' => '
',
  );

  //if the form has been changed, update the appropriate fields
  if ( isset($form_state['triggering_element']) ) {
    $callback = _name_to_callback($form_state['input']['_triggering_element_name']);
    if ($callback == "_udr_update_data") {
      _udr_update_data($form, $form_state, $data);
    }
    elseif ($callback == "_udr_delete_data") {
      _udr_delete_data($form, $form_state, $data);
    }
  }
  return $form;
}

I would like to make this button make a pop-up warning that asks the user if he/she would like to really delete the data.  If yes, then delete.  If no, then don't delete.

I have tried various methods such as:

'#attributes' => array('onclick' => 'if(!confirm("Really Delete?")){return false;}'),

And also:

    // Add an delete button to the end of every row
    $form[$row_name][sizeof($data['columns']) + 1] = array (
      '#type' => 'submit',
      '#submit' => array('udr_submit_rebuild'),
      '#value' => t('Delete Row'),
      '#name' => $row . '-_udr_delete_data',
      '#prefix' => "",
      '#suffix' => "	",
      '#ajax' => array (
        'wrapper' => "row-$row",
        'callback' => '_udr_ajax_handler',
        'progress' => FALSE,
      ),
      '#weight' => 1001,
    );
  }

  if (isset($form_state['triggering_element']) && $form_state['triggering_element']['#value'] == t('Delete Row')) {
    $form[$row_name][sizeof($data['columns']) + 1]['#value'] = t('Really Delete?');
    $form[$row_name][sizeof($data['columns']) + 1]['#submit'] = array('udr_submit_handler');
  }

  $form['table_end'] = array(
    '#prefix' => '
',
  );

  //if the form has been changed, update the appropriate fields
  if ( isset($form_state['triggering_element']) ) {
    $callback = _name_to_callback($form_state['input']['_triggering_element_name']);
    if ($callback == "_udr_update_data") {
      _udr_update_data($form, $form_state, $data);
    }
    //~ elseif ($callback == "_udr_delete_data") {
      //~ _udr_delete_data($form, $form_state, $data);
    //~ }
  }
  return $form;
}

function udr_submit_rebuild($form, &$form_state, $data) {
    $form_state['rebuild'] = TRUE;
}

function udr_submit_handler($form, &$form_state, $data) {
  $callback = _name_to_callback($form_state['input']['_triggering_element_name']);
  if ($callback == "_udr_delete_data") {
    _udr_delete_data($form, $form_state, $data);
    $form_state['rebuild'] = TRUE;
  }
}

The correct way to fix this issue is to is to attach a JavaScript watch to the button and have the trigger make a confirm dialog pop up and then make a JavaScript request from the user's browser back to a URL with a parameter of the element to be deleted at the end of it, then fade out the rows from the HTML table and make sure the zebra striping is correct, then secure that second URL to have the same permissions as the original page, then receive the parameter at the called URL and process the callback you had originally intended to run:

PHP:

onclick="Drupal.dccAdmissions_confirm_delete('$rec->pi_firstname $rec->pi_lastname', '$rec->pi_id . ', '$rec->pi_id', jQuery(this) );

JavaScript:

( function($) {
  Drupal.dccAdmissions_confirm_delete = function( in_name, id, object ) {
    if ( confirm( 'Do you want to delete the application for ' + in_name + '?' ) ) {
      $.ajax({
        type: 'GET',
        url: '/admissions/application/delete/' + id,
        success: function(data) {
          if ( data == 'DELETED' ) {
            // Remove the specific row
            $(object).parents('tr').fadeOut( 1000 );
            $(object).parents('tr').remove();
            $('#dccadmissions-application-management-form tr:nth-child(odd)').addClass( 'odd' );
            $('#dccadmissions-application-management-form tr:nth-child(odd)').removeClass( 'even' );
            $('#dccadmissions-application-management-form tr:nth-child(even)').addClass( 'even' );
            $('#dccadmissions-application-management-form tr:nth-child(even)').removeClass( 'odd' );
          } else {
            alert( 'Delete failure: ' + data );
          }
        }
      });
    }
  }
  Drupal.dccAdmissions_confirm_reset = function( in_name ) {
    return confirm( 'Do you want to reset the application for ' + in_name + '?' );
  }
})(jQuery);

Make a menu hook:

function dccAdmissions_menu() {
  $items['admissions/application_management'] = array (
    'title' => t("Admissions Online Application Management"),
    'page callback' => 'dccAdmissions_application_management_content',
    'type' => MENU_CALLBACK,
    'access callback' => 'dccInGroup',
    'access arguments' => array( 'Admissions' ),
  );

Check your cases:

/*
 * Page callback for application management pages.
 */
function dccAdmissions_application_management_content( $arg1 = 'new', $arg2 = 0, $arg3 = '' ) {
  include_once "application-management.data.inc";

  $module_path = drupal_get_path( 'module', 'dccAdmissions' );
  $output = array(
    '#attached' => array(
      'css' => array( $module_path . '/css/application-management.css', ),
      'js'  => array( $module_path . '/js/application-management.js', ),
    ),
  );

  switch( $arg1 ) {
    case 'delete':
      $message = _dccAdmissions_application_management_delete( $arg2 );
      return drupal_json_output( $message );
      break;

Then delete your data:

function _dccAdmissions_application_management_delete( $id ) {
//... your delete code here...


hook_apachesolr_process_results having no impact on results I've posted this at d.o, but I'm hoping maybe someone here might be able to help. (The documentation on apachesolr for D7 is so far rather depressing.)

I wrote a module for a D6 site implementing hook_apachesolr_process_results to modify the snippets of text shown on the search results page. That worked like a charm. We've now moved on the D7. I've again written a module to implement the same hook. This is a lowest-comment-denominator version of the function:

function mysearch_apachesolr_process_results(&$results, $query){
  foreach($results as $id => $result){
    $results[$id]['snippet'] = "FOOBAR";
  }
  debug_to_file($results);
}

The call at the end debug_to_file is a utility function I use to print_r a variable to a file. That call proves that a) my code IS indeed getting run and b) that the $results variable has been changed internally. However, my search results page has nary a FOOBAR to be found!

Could it possibly be an interaction between apachesolr and another module? Apachesolr and my theme (fusion 7.x-1.x-dev)?

It'd even be helpful here to get an indication of what to try next as far as debugging. Any advice would be useful!

FTR, I'm using Drupal 7 with the ApacheSolr Search and Framework modules at version 7.x-1.0-beta12.

Grr. Someone outside of StackExchange suggested a few routes of debugging that would weed out issues having to do with interaction of my code with other code. One of those suggestions was to go back to a default theme and see if my change showed there. It did. I talked to my themer to see if he had any insight.

And, that's when we hit the "a-ha" moment: We were using a custom theme based off of Fusion. (Incidentally, when I switched to stock Fusion, everything worked correctly.) At that point, it was just a matter of flipping through all of the "Appearance" settings to find that under search results none of the checkboxes were ticked. Guess what happened when I ticked the "snippet" checkbox?? Yeah....

Though, we did learn something good here, at least: If you create a new theme as a custom sub-theme of an existing theme, your subtheme does not inherit the settings of its parent theme.


Get internal path from external URL Is there a way to get Drupal internal path from the external URL? I need to get node id (or any other internal path) from the URL that user specifies in the textfield. External URL in this case is not the URL of current page, it is arbitrary URL that is entered by user.

For example:

Base URL: http://www.example.com/drupal

Alias of node/101: foo/bar

User input: http://www.example.com/drupal/foo/bar or http://www.example.com/drupal/?q=foo/bar

Expected result: node/101 or foo/bar

The problem explained:

drupal_get_normal_path() only returns normal path if internal alias is given. In this case internal alias from external URL needs to be extracted but there are no internal Drupal function that would do that directly.
If site has Clean URLs enabled, request path in external URL can either be in "q" argument (?q=foo/bar) or in URL itself (/drupal/foo/bar).

Dull Ax....

$path='';
$with_trailing_slash=$base_url . '/';

if (strpos($user_input, $with_trailing_slash)===0) {
  $user_input=str_replace($with_trailing_slash, '', $user_input);
  if (strpos($user_input, '?q=')===0) {
    $path=substr($user_input, 3);
  } else {
    $path=$user_input;
  }
} else {
  // this isn't on the local system so there is no way to figure it out
}

if ($path) {
  $normal=drupal_get_normal_path($path);
}


Which modules should be listed as dependency of my module? If my module calls a function of another module, that other module should be listed as a dependency of my module.

Now my module only provides some field handlers for the Views module. On the one hand, my module is useless without the Views module. On the other hand, my module does not call any functions or methods provided by the Views module.

Should I add Views to the list of dependencies for that module? If yes, would that change if my module provides other functionality unrelated to views (like custom pages)?

Note that I used Views only as an example. The question applies to all optional modules, that define hooks.

The Drupal.org .info file documentation does not define a dependency in itself other than stating a module cannot be enabled if a dependency is not present.

I guess you have to decide for yourself what you would consider a dependency. Personally, if a user needs to use Views in order to use your module than you would want to make sure it is installed.

If you don't want to make a module a dependency because it only supports secondary functionality in your module, you can use module_exists() to make sure your module doesn't die if the function it is calling is not there.


How do I support text formats for an entity property? I have a custom entity I've created following this basic SitePoint tutorial. My custom entity has just two properties, a name and description. My entity is not fieldable (maybe it needs to be?.

I want to make the description support text formats so it's not just interpreted as plain text. Ideally the user could choose text formats like they could for something like a text field added thru the field UI, but since my entity is not fieldable and has no UI for adding fields, I'm not sure where to go with this?

You'll need another property on your entity to hold the format.

In your entity form builder, use a text_format element, and use a validate to move the desired values into place:

$form['description_placeholder'] = array(
  '#type' => 'text_format',
  '#title' => t('Description'),
  '#format' => empty($entity->description_format) ? 'full_html' : $entity->description_format,
  '#default_value' => empty($entity->description) ? '' : $entity->description,
);

$form['#validate'][] = 'MYMODULE_entity_validate';

...

function MYMODULE_entity_validate($form, &$form_state) {
  $form_state['values']['description'] = $form_state['values']['description_placeholder']['value'];
  $form_state['values']['description_format'] = $form_state['values']['description_placeholder']['format'];
}

When you render, use:

 $formatted = check_markup($entity->description, $entity->description_format);


"list" plugin does not exist after upgrading from Drupal 8.3.x to 8.4.2 How can I tell exactly what is missing and from which module? (I assume it's draggableviews)

How can I remedy this error - or is it in the hands of a contrib module developer or where can I go to see how to contribute the missing plugin?

This is the output of drush @badev updb.

 ---------------- --------------------------------- --------------- -------------------------------------------------------------------------
  Module           Update ID                         Type            Description
 ---------------- --------------------------------- --------------- -------------------------------------------------------------------------
  draggableviews   8104                              hook_update_n   Implements hook_update().
  comment          enable_comment_admin_view         post-update     Enable the comment admin view.
  dblog            convert_recent_messages_to_view   post-update     Replace 'Recent log messages' with a view.
  field            remove_handler_submit_setting     post-update     Remove the stale 'handler_submit' setting for entity_reference fields.
  node             configure_status_field_widget     post-update     Load all form displays for nodes, add status with these settings, save.
  system           classy_message_library            post-update     Clear caches to ensure Classy's message library is always added.
  system           field_type_plugins                post-update     Force field type plugin definitions to be cleared.   @see
                                                                     https:www.drupal.orgnode2403703
  views            revision_metadata_fields          post-update     Fix table names for revision metadata fields.
 ---------------- --------------------------------- --------------- -------------------------------------------------------------------------

 Do you wish to run the specified pending updates? (yes/no) [yes]:
 > yes

 [notice] Executing draggableviews_update_8104
 [error]  The "list" plugin does not exist.
 [ok] Performing draggableviews_update_8104
Array   Array
 [success] Cache rebuild complete.
 [success] Finished performing updates.
Connection to drupal8vm.dev closed.

This is solved now. I think that there was a mismatch between the PHP/ Drush / Drupal 8.4.3 versions.

This confused me so I include a table below of what is now working for me. I used it as a checklist to ensure that I had both a dev Drupal 8.3.7 and a dev Drupal 8.4.3 running in parallel.

Despite what the documentation says I think Drush 8.1.15 is not suitable for Drupal 8.4.3 and yes, there are some Drush 9.0.0-rc1 commands that don't work as expected  - like dumping SQL and redirecting SQL files to drush sqlc -  but it is workable.

Bits and pieces in each of existing and future Drupal

               iMac               MacBook
PHP VM         7.1.12             7.1.12
PHP Host       7.1.12             7.1.12
Drush VM       8.1.16-dev         ~9.0
Drush Host     8.1.15             ~9.0
Drupal Core    8.3.7              8.4.3
MySQL          5.7.20             5.7.20   (Required MySQL 5.5.3/MariaDB 5.5.20)


Daily cron job to download and email Webform submissions file On a Webform I can download a tsv (tab delimited) file and select the 'Only last submissions since download' option.

What I want to do is have a daily cronjob which does the same thing and emails this file automatically.

How would I do this? Is there any existing Module to do this in Drupal 7?

Using a custom module, you can implement hook_cron() to export the csv and send an email:

function MODULE_cron()
{
    //this is the function that creates the csv, you'll need to research how to use it properly.
    webform_results_download($node, $export_info);
    //send email
}

As far as sending email, you can use php mail or drupal_mail(), but phpMailer might be the easiest to use.


Different responsive image per breakpoint I have the following scenario - the main page banner should have at any time 1 of 3 images displayed at a given viewport size. These images are art-directed, that is to say, that will differ in content and layout and are created with desktop, tablet and mobile in mind. (All of this is despite my protests).

I'm wondering what are the options for requesting the correct image at the appropriate viewport size? (Optimisation is very much a concern here! I don't want to serve 3 images only to use 1.) My understanding when it comes to D8 and responsive images is that D8 will create versions of the same image for the srcset rather than giving the option to serve different images at different viewport sizes.

So what are my options here? Perhaps the best option is to have 3 image fields that are outputting directly into a srcset in a banner template.

Are they completely different images?

Then I'd use Paragraphs module and create a heavily customized template outputting your different images as <source srcset="..." media=""> inside a single <picture> tag. Modern browsers will only download the correct version for the visitors viewport. (Manually add a polyfill library if required.)

Is there one large source image rendered with different focal points or different crop areas (Modules "Focal point" or "Image widget crop")?

Then I'd create a specific breakpoint group only for your banner. Create a responsive image style for this group and use Select a single image style for each individual breakpoint width. Drupal will then automatically render a similar markup as above and also add polyfills for older browsers.

In any case, definitely use a <picture> tag with multiple <source srcset="...filename..." media="(...mediaquery...)">s for art directed responsive images.


Best way to use image styles with Media and WYSIWYG? Up to now, I've been using the Insert + WYSIWYG + CKEditor to insert images with specific Image Styles in a wysiwyg interface. This works well, and it's very easy to select and apply image styles (including colorbox variants) using Insert.

I'm currently testing Media (7.2x) + WYSIWYG + CKEditor as an alternative, and want to make sure I understand how to best use image styles in this context.

Based on a great write-up here (http://www.58bits.com/blog/2013/03/06/how-to-add-captions-to-images-in-drupal), it looks like one way to use Image Styles with Media is to do something like this:

Create desired image styles to use in WYSIWYG editor
Add view mode(s) as needed to the Image file type
Set view mode(s) to use desired image styles under Manage File Display
Choose "Format" (view mode) when embedding Media

Ultimately, this is more powerful than Insert, since the view modes can manage more than just the image (i.e. other fields like title, alt, and more) but it's a little clunky. For one thing, you'd need to add a new view mode for each image style that you want to have access to when embedding (?)

My question: is this currently the best way to use image styles when embedding images using Media (7.2x) + WYSIWYG + CKEditor?

It completely depends on your requirement. If you are looking to apply particular styles through wysiwyg then view styles is definitely the right option.

If you need image style (height and width) to be chosen during wysiwyg then go for this option

a) Media + Wysiwyg -: https://drupal.org/comment/8009717#comment-8009717

b) Wysiwyg + Ckeditor -: https://drupal.org/node/1956778 (patch 37)


Duplicate Meta description on shared node across multiple subdomains I have a drupal site with multiple subdomains which share a single node. I installed Yoast SEO for Drupal and added title / description etc. for each node. Now the problem is that it shows same meta title and description for all sites (subdomain). Any idea on how to resolve this issue.

I haven't used that module (looks cool!), but it does depend on metatag, which is probably what's providing the title & description fields. The metatag module saves its configuration in a database table metatag_config, which is probably shared across all of your subdomains.

It looks like you can have tokens in your config, so for example, we use [node:title] [site:name] for our page title config. And if you wanted an unique title for each subdomain, you could just specify a separate site name for each one.

We use subdomains (www, m, staging, dev, etc) and we're fine to share the node's title & description across all of them. The thing we do want unique is the canonical meta tag, so if a search engine comes across duplicated content on a subdomain, it won't take anything away from the original. So we'll specify the full domain in the canonical url like this:

https://www.example.com/[current-page:url:path]


How do I let users cancel their account with JWT / JSON:API? I am making an Ionic app with Drupal as the backend.  Users log in via JWT.  I'm using JSON:API to send data to Ionic.  Now I want to allow users to cancel their accounts in the app (by JSON:API) instead of forcing them to log into the Drupal website and cancel there.
How can I do that?

This method uses the JSON:API Resources module.
It assumes:

Upon cancellation, blocking the user is OK.  (Admins will manually delete the accounts completely later.)
Logged-in users will simply make a GET request to www.example.com/jsonapi/MYMODULE/cancelaccount to cancel their accounts (the app will provide an "Are you sure?" dialog and so forth).

There is probably a better way to do this but I am sharing my solution here because a Google search didn't reveal anything on this topic.
What to do
First, create a custom module.
Then, in MYMODULE.routing.yml:
MYMODULE.user_cancel:
  path: '/%jsonapi%/MYMODULE/cancelaccount'
  defaults:
    _jsonapi_resource: Drupal\MYMODULE\Resource\MYMODULEUserCancel
  requirements:
    # Give all authenticated users permission.
    _permission: 'view own commerce_order'
  options:
    no_cache: 'TRUE

Next, in MYMODULE/src/Resource/MYMODULEUserCancel.php:
<?php

namespace Drupal\MYMODULE\Resource;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Logger\LoggerChannelFactory;
use Drupal\Core\Session\AccountInterface;
use Drupal\jsonapi\JsonApiResource\LinkCollection;
use Drupal\jsonapi\JsonApiResource\ResourceObject;
use Drupal\jsonapi\JsonApiResource\ResourceObjectData;
use Drupal\jsonapi\ResourceResponse;
use Drupal\jsonapi\ResourceType\ResourceType;
use Drupal\jsonapi\ResourceType\ResourceTypeAttribute;
use Drupal\jsonapi_resources\Resource\EntityQueryResourceBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;

/**
 * Processes a request for a collection containing a user's article nodes.
 *
 * @internal
 */
class MYMODULEUserCancel extends EntityQueryResourceBase implements ContainerInjectionInterface {

  /**
   * The current user account.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected AccountInterface $currentUser;

  /**
   * Logger factory.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactory
   */
  protected $loggerFactory;

  /**
   * Constructs a new EntityResourceBase object.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user.
   * @param \Drupal\Core\Logger\LoggerChannelFactory $logger_factory
   *   The Watchdog logger.
   */
  public function __construct(AccountInterface $account, LoggerChannelFactory $logger_factory) {
    $this->currentUser = $account;
    $this->loggerFactory = $logger_factory->get('MYMODULE');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('current_user'),
      $container->get('logger.factory'),
    );
  }

  /**
   * Process the resource request.
   *
   * Code example:
   * https://git.drupalcode.org/project/jsonapi_resources/tree/9.x-1.x/tests/modules/jsonapi_resources_test/src/Resource.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   * @param \Drupal\jsonapi\ResourceType\ResourceType[] $resource_types
   *   The route resource types.
   *
   * @return \Drupal\jsonapi\ResourceResponse
   *   The response.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function process(Request $request, array $resource_types): ResourceResponse {
    $uid = $this->currentUser->id();
    // Make sure that we do not try to cancel user 1 or anonymous.
    if ($uid !== 1 && $uid !== 0) {
      $user_storage = $this->entityTypeManager->getStorage('user');
      $current_user = $user_storage->load($uid);
      // See: https://drupal.stackexchange.com/a/204422.
      // Send the user the "account blocked" confirmation email.
      _user_mail_notify('status_blocked', $current_user);
      $current_user->set('status', FALSE);
      $current_user->save();
      $this->loggerFactory->notice("User account for UID @uid cancelled by JSON:API.", [
        '@uid' => $current_user->id(),
      ]);
    }

    // Some data to return with JSON:API.
    $custom_field_data = [
      'cancelled' => TRUE,
    ];

    $links = new LinkCollection([]);
    $resource_type = reset($resource_types);
    // To disable caching, set metadata.
    $cacheability = new CacheableMetadata();
    $cacheability->setCacheMaxAge(1);
    $primary_data = new ResourceObject(
      $cacheability,
      $resource_type,
      $current_user->uuid(),
      NULL,
      $custom_field_data,
      $links
    );
    $top_level_data = new ResourceObjectData([$primary_data], 2);
    $response = $this->createJsonapiResponse($top_level_data, $request, 201, []);
    $response->addCacheableDependency($cacheability);

    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public function getRouteResourceTypes(Route $route, string $route_name): array {
    $fields = [
      'drupalUid' => new ResourceTypeAttribute('drupalUid'),
      'status' => new ResourceTypeAttribute('status'),
    ];
    $resource_type = new ResourceType('current_user', 'current_user', NULL, FALSE, TRUE, TRUE, FALSE, $fields);
    // @todo Add role entities as a relatable resource type.
    $resource_type->setRelatableResourceTypes([]);
    return [$resource_type];
  }

}


"Please select category" as default value in a select list Similar to how the search box on many sites has a default value of "search", how do I give a select list a default value without making that value a valid option in the list of options. See example below:

For adding text to your input field, write a custom module and place the code in there

function yourmodule_form_alter(&$form, &$form_state, $form_id){
    if($form_id == "your_form"){
     $form['some_element']['#attributes']['placeholder'] = t('Select Category');
}


How to map user/password to a mobile theme? I'm working on a mobile version of a forgot password page, the problem I have is the mobile theme is triggered when users are on a page with a URL like:

example.com/m/about

Here, about would be a node and it's a mobile version of the example.com/about.

So I read through drupal documentation and looked at Customizing and Overriding User Login page...but the issue I have is, how do I go about mapping example.com/user/password to a mobile version since it's not a node it's a template (node--user.tpl.php)?

You should be able to get around your problem (I say should because I haven't actually tried this):

Make a custom module that creates a menu item for the required url and makes it call the user password form.

/**
 * Implements hook_menu().
 */
function MODULENAME_menu() {
  $items = array();

  // A replica of the password reset page for mobile.
  // Based on the original menu item in user_menu().
  $items['m/user/password'] = array(
    'title' => 'Request new password',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_pass'),
    'access callback' => TRUE,
    'type' => MENU_NORMAL_ITEM,
    'file' => 'user.pages.inc',
    'file path' => drupal_get_path('module', 'user'),
  );

  return $items;
}

I foresee you having to do this for some other pages too.

Personally I would probably not make a mobile site in this fashion, I would use the same pages for mobile and non-mobile and then make them look different based on screen size.


theme_hook_suggestions is ignoring my suggestions I'm working in Drupal 7.

I'm trying to add a custom template file for a few pages I'm creating. I've done so in hook_preprocess_page in my template.php file.

This is the scenario:

I have four "Basic Page" pieces of content that will use the same template file. I've already coded page.tpl.php for other "Basic Page" content. The reason I want this template is because the look of these four basic pages is different from other pages. What I've done is added my suggestion to the theme_hook_suggestions array. It's ignoring what I'm adding. Just a note: after every step I'm clearing my caches. It isn't that.

I've tried this:

$variables['theme_hook_suggestions'][] = 'newbies';

This will add the 'newbies' suggestion to the array, but creating a 'newbies.tpl.php' file gets me nowhere. It's ignored. I've gone as far as doing this:

$variables['theme_hook_suggestions'] = array(0=>'newbies');

Which erases the suggestions array and adds only my suggestion, which I've verified with krumo. This also doesn't do anything and is ignored. My site doesn't even break when I do it.

From what I've read about theme_hook_suggestions, it would seem that Drupal only wants template suggestions for templates that it defines. For example, just creating an arbitrary template file (in this case 'newbies') instead of some system defined one like 'page--type--system--node......' etc.. will never work.
I've decided to rule that out as being truth for now because I refuse to believe that a design flaw of that magnitude could be introduced into any software.

What am I missing?

You're missing how the framework is designed.

If you're doing anything with hook_preprocess_page() you are affecting the 'page'.

The default template for page is 'page.tpl.php'.

If you want to 'override' this template Drupal needs to understand what's going on so has some conventions.

page--[front|internal/path].tpl.php

page--node--edit.tpl.php
page--node--1.tpl.php
page--node.tpl.php
page.tpl.php

"Theme hook suggestions are made based on these factors, listed from the most specific template to the least. Drupal will use the most specific template it finds"

See: http://drupal.org/node/1089656 and http://drupal.org/node/223440#custom-suggestions

In your case, your defining 'newbies.tpl.php' and expecting this to work but it's still going to use 'page.tpl.php' so to override this you want to do 'page--newbies.tpl.php' (same as 'page--node.tpl.php').

More to the point, you don't even need to set this with hook_preprocess_page() as Drupal will follow those conventions automatically.


D7 form field #ajax callback not called on autocomplete field I have an entity reference field, and I'd like to do some ajax so that when a value is selected for that field, some text is displayed in a div below the field. Since it's on a node edit form, I'm using a form alter hook:

/**
 * Implementation of hook_form_FORM_ID_alter()
 */
function mymodule_form_blog_node_form_alter(&$form, &$form_state, $form_id) {
  $form['field_video_reference']['#ajax'] = array(
    'callback' => 'mymodule_video_ajax_callback',
    'wrapper' => 'my-path-div',
  );

  $form['my_path'] = array(
    '#markup' => t('My path'),
    '#prefix' => '
',
    '#suffix' => '
',
    '#weight' => 6,
  );

  if (!empty($form_state['node']->field_video_reference)) {
    $form['my_path']['#markup'] = 'Token path: http://www.mysite.org/node/' . $form_state['node']->field_video_reference['und'][0]['target_id'];
  }
}

function mymodule_video_ajax_callback($form, $form_state) {
  return $form['my_path'];
}

The code works fine when a the form is displayed and the field already has a value.  However, the most likely use will be when the node is first being created, so I want this to trigger when a value is first added.  The problem is, my callback is not being triggered at all.  I'm following the first example in the "Javascript in Drupal" chapter in "Drupal 7 module Development," so from what I see, I it should be called when the field value is changed.  Does this not work for fields that are already using ajax to get a value in the first place (i.e. an autocomplete field like this one), or is there something else I'm  missing?

Thanks.

UPDATE: In case it is an issue with doing this on an autocomplete field, I added another test field that is a select list and attached the ajax to it as above, but the form is still not rebuilt when I select a value.

I think the problem is that $form['field_video_reference'] is a container and you want to attach the ajax event to the actual text field element.

If you inspect the $form array you should see the correct place to put it. In needs to be at the same level as the #type => 'textfield' (or entity reference) property.

I think the path will be something like:

$form['field_video_reference'][LANGUAGE_NONE][0]['value']['#ajax'] = array(
    'callback' => 'mymodule_video_ajax_callback',
    'wrapper' => 'my-path-div',
);


REST GET without caching Using this tutorial Drupal Console's drupal gprr command, I've created a custom REST resource in Drupal 8. I'm able to use this resource to retrieve a simple JSON object that says hello to the current user by doing a GET on:

http://localhost/example/hello?_format=json

The JSON returned then looks like this:

{ "hello": "tyler" }

This is to be expected, as I'm logged in. But when I logout, and do another GET on the resource, the same result is returned:

{ "hello": "tyler" }

Doing a full Drupal cache clear fixes this issue, but I'd like to specifically disable caching on this resource. How can I do that?

As a workaround, I thought adding a time stamp to the query string would work:

http://localhost/example/hello?_format=json&time=123456789

But that also returns the exact same result, no matter what time stamp value is in the query string.

For brevity, here's the skeleton code for building the GET resource:

class ExampleHello extends ResourceBase {

  /**
   * {@inheritdoc}
   */
  public static function create(/* ... */) {
    return new static(/* ... */);
  }

  /**
   * Constructs a Drupal\rest\Plugin\ResourceBase object.
   */
  public function __construct(/* ... */) {
    parent::__construct(/* ... */);
    // ...
  }

  /*
   * Responds to GET requests.
   */
  public function get() {

    $account = \Drupal::currentUser()->getAccount();
    if (!$account->id()) {
      return new ResourceResponse(array(
        'welcome' => 'visitor'
      ));
    }
    return new ResourceResponse(array(
      'hello' => $account->getAccountName()
    ));
  }

}

Is there a configuration/setting I need to set on this plugin to disable caching on GET requests?

You want to read the Cacheability documentation. it says render arrays, but it also applies to response objects.

ResourceResponse implements CacheableResponseInterface, which has the addCacheableDependency method.

If in any way possible, you want to avoid disabling the cache (which you would do by setting the cache max age to 0), but add the necessary cache contexts and cache tags.

In your cache, that means all you need to do is $response->addCacheableDependency($account).

You also don't need getAccount(), just use currentUser() directly, it's a proxy.


How can I do a custom form redirect on the user registration form? I added a custom submit function to the user registration form. I want to be able to redirect to the user profile edit. How can I get the uid of the record that is about to be created? global $user doesn't work:

function my_user_register_submit ($form, &$form_state) {
  global $user;
  $form_state['redirect'] = 'user/' . $user->uid . '/edit?registration=1&destination=blahblah';
}

Edit:

My use case is this: after registration I want to redirect the user to the "edit profile" page to complete the remaining profile fields. When they "skip" that or complete the form they go to their profile page.
However, when a ?destination parameter is passed into the register form I want to carry that value to the "edit profile" page and then direct the user to that destination page when they are done.

Login Toboggan has an option for this whereby you can use %uid as an argument for the redirect URL.

Literally a text box where you'd type /user/!uid/edit

It's also got a whole host of awesome features that are worth checking out :)


why are users logged out after 2 days of not logging in We got LDAP SSO working for our site. Employees go to the site everyday and everyday they do not have to input their credentials... until Monday. I believe this has to do with cookies maybe? I think if the employees have not logged in in a couple of days (weekend) then they have to log back in. Every Monday they have a http authentication dialogue box (LDAP Authentication from the /user/login/sso url). It saves their credentials (if they hit remember my password), but they don't like hitting the enter key.

My /admin/config/people/ldap/authentication settings look like this:

I then found this post: Why is session.cookie_lifetime set to 23 days?, where they say that in drupal it might have a session.gc_maxlifetimesetting in settings.php that is set to 23 days, but that the session.cookie_lifetime is set to 2.3 days. And that if the user doesn't visit the page withing 2.3 days then they start a new session or something. Does this mean if I adjust the ini_set('session.cookie_lifetime', 200000); to like 4 days that the employees wont need to hit enter anymore?

The answer here explains the difference between the cookie types and when they destroy the session: Why is session.cookie_lifetime set to 23 days?

To answer your question specifically:

If you extend the session.cookie_lifetime to be longer, the session will last longer and users will less frequently require to login. If the user opens the page within session.cookie_lifetime from the last visit, the session will be extended for another session.cookie_lifetime. This can be repeated several times, but never longer then session.gc_maxlifetime after which a user is always forced to log in again.

If you extend the session.cookie_lifetime to last for eg. 4 days (so it survives the weekend), users that always open the page on workdays will have to login once every 23 days (session.gc_maxlifetime). You can also extend this value to last as long as you want.

Please keep in mind that although hitting the enter might be annoying, if security is part of your job as well, it might not be a good idea to have sessions lasting for long periods of time. Have them survive the weekend by having them last a day longer will not cause much problems, but allowing them to extend for ever and ever (session.gc_maxlifetime) could introduce security vulnerabilities.


How to change operator in schema.xml and configure site for AND search I am using Solr search with drupal.Its working fine on my site but the problem is
i needed the search to be a specific to the searched content.
If i searched for "assembly and key",the search result showing all results which is having the world assembly and key also.

But I needed the result like wherever this particular word is found not the separate.
when i search for "assembly and key" it is giving me around 55 results and when i am searching "assembly+and+key", it is giving only 1 result which is i want.
So please let me know how to do it.

I have tried to change solr/conf/schema.xml for AND operator also tried to add code in apachesolr module file for changing the mm parameter but it doesn't work.

You need not to edit the Solr_Base_Query.php file just add the following line of the code in your module

function modulename_apachesolr_query_prepare($query){
$query -> addParam('q.op', 'OR');

}


Add taxonomy term in popup I have a select list with some options. But now I also want an option Other. And when you select the Other option there has to open a pop-up screen with the add term to vocabulary form in it. The term should not be added directly to the vocabulary, it should be "disabled" first so the administrator can approve them.

I know how to get the taxonomy form (taxonomy_form_term, drupal_get_form, drupal_render_form) but I have some other questions:

How can I open the popup and show call the function in my module to render the form? Should I add another option to my select list?
How can I make sure when you add it, it doesn't add directly to the vocabulary (admin has to click approve)

For the first part of your question, set an event listener to bind when the other option is selected, and then display your popup. I would suggest setting a custom state (see the Form API) and listening for that state. The example given in the states API explains better:

  Each remote condition is a key/value pair specifying conditions on the
  other element that need to be met to apply the state to the element:

array(
  'visible' => array(
    ':input[name="remote_checkbox"]' => array('checked' => TRUE),   ), )

  For example, to show a textfield only when a checkbox is checked:

 $form['toggle_me'] = array(
   '#type' => 'checkbox',
   '#title' => t('Tick this box to type'),
 ); $form['settings'] = array(
     '#type' => 'textfield',
     '#states' => array(
     // Only show this field when the 'toggle_me' checkbox is enabled.
     'visible' => array(
       ':input[name="toggle_me"]' => array('checked' => TRUE),
 ),
),

  );

jQuery UI Dialog would be a good solution for the popup.

For the second part, there is a module to handle just this situation, so that taxonomy terms can be moderated and approved. Taxonomy Other:

  Use case example: You have a taxonomy vocabulary called 'Organization
  type' and you want to allow users to be able to choose '- Other -' and
  add their own type. You want to use a simple select list and to keep
  the list small to encourage people to use the types you've provided.


How to choose the default (or any) CKEditor toolbar? OK, I'm obviously missing something.  I've installed CKEditor into a D7 site, and all's well.  The only problem is I can't figure out how to specify the toolbar that will come up by default in CKEditor-enabled fields.  I've defined a new toolbar in .../ckeditor/ckeditor/ckeditor.config.js, but I haven't found any place in the site's config options (or the code, for that matter) that let me say that I want CKEditor to put up this particular toolbar.  For that matter, I don't see any way to be able to choose the other toolbars in ckeditor.config.js (like DrupalAdvanced and DrupalFull).  Any clarification out there?  Thanks!

I finally figured this out: See http://drupal.org/node/1434814#comment-5583354 for the solution.  The most important bits are:

If you're just using the basic CKEditor module, ckeditor.config.js is completely irrelevant to getting your toolbar set up. Ignore it.
CKEditor toolbars are associated with text formats, like "Filtered HTML" or "Full HTML" (or, presumably, other text formats you might define). Each text format can be connected to exactly one toolbar; when a textbox with that text format appears, its toolbar will be presented.


Setting #element_validate in a form (not form alter) removes original #element validation I have an element with set #element_validate (in hook_element_info) and I use this element in a custom form. The problem is that when I try to add an additional #element_validate to the element in the form it overrides the original validate callback (the one set in hook_element_info).

So my question is, is there any way how to add an additional #element_validate in a custom form without having to use form_alter?

hook_element_info:

'ELEMENT_NAME' => array(
  '#input' => TRUE,
  '#tree' => TRUE,
  '#process' => array(..),
  '#element_validate' => array('original_validate'),
),

form:

$form['TST'] = array(
  '#type' => 'ELEMENT_NAME',
  ...
);
$form['TST']['#element_validate'][] = 'new_validate';

And then only new_validate is present when on 'process' callback of the element (as well as when the form is build). When I don't set the 'new_validate' the 'original_validate' is still present on 'process'.

Other elements (tried a few date ones) seem to behave the same way. E.g. #element_validate added in form declaration overrides the own element's one defined in hook_element_info.

You can create validate callback for the entire form and validate the element in that callback.$form['#validate'][] = 'new_validate';

Also separate validate callbacks can be attached to 'submit' ('preview', 'cancel' etc) buttons within the form. And the element can be validated there as well.

$form['submit_button']['#validate'][] = 'new_validate';


How to add local task links to referenced entities for a specific content type? I have a content type with some entity reference fields to another content types. I want to add local task tabs to the node view page, to link those referenced node. However I cannot figure it out how to do it only for the specific content type.

I have created a my_module.links.task.yml file with following contents:

my_module.my_content.my_content_type:
  route_name: entity.node.canonical
  title: Overview
  parent_id: entity.node.canonical
  weight: 0
  class: '\Drupal\my_module\Plugin\Menu\MyContentTab'

my_module.my_content.my_referenced_node:
  route_name: entity.node.canonical
  title: Referenced content
  parent_id: entity.node.canonical
  weight: 10
  class: '\Drupal\my_module\Plugin\Menu\MyReferencedContentTab'
# ... More tabs to the other referenced nodes

The classes are working as they should, and providing the tabs to the referenced nodes correctly. However the tabs are also showing on all content types.

How can I make them show only on the specific content type?

The reason these tabs show up on all of your content types is that entity.node.canonical is the base route for all nodes. Since you're setting entity.node.canonical as the parent_id, Drupal thinks you want these tabs displayed on every node page.

The easiest way to achieve your goal is probably to implement hook_menu_local_tasks_alter() with code similar to this:

  if ($route_name === 'entity.node.canonical') {
    /** @var \Drupal\node\Entity\Node $node */
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node->bundle() !== 'my_bundle') {
      $data['tabs']['my_module.my_content.my_content_type']['#access'] = FALSE;
      $data['tabs']['my_module.my_content.my_referenced_node']['#access'] = FALSE;
    }
  }

Because Drupal performs upcasting on this route, you can get a reference to the current node directly from routeMatch() as a parameter, and then compare its bundle to your custom content type. When they don't match up, we set access to FALSE for those tabs.

I think another approach that would probably work is to override the getRouteParameters() method of your LocalTaskDefault classes and use similar logic; if the current node isn't your custom content type, then return an empty array of route parameters.

A third approach might be to create a custom route for your specific content type and then assign that route as the parent_id for these tabs.


Best mobile theme for iOS devices? Can anyone please tell me the best mobile theme I could use for iOS devices? I tried the iUI theme but it doesn't display the table with the info properly :)


How to disable CACHE in VIEW PAGE display DRUPAL 8

I am using VIEW module to create a page which loads data from a database table.

Seems this view page is caching because whenever I add a new record in this table via custom input form, it doesn't show on view page immediately after refresh. I can clearly see this new entry in the database table but not on view page.

Then I have to manually clear cache from the site > performance section and then I can see new entry on the view page.

Please note that database table is a custom table and I am using hook_views_data() to add custom table fields in the view page.

BTW I had disabled 'Disable views data caching' on '/admin/structure/views/settings/advanced' page but it has no effect on my view page.

Can anyone please advise what should I do to avoid CACHE?

Thanks.

You have to add a cache tag to the View, the name is arbitrary, for example custom-data-list.

You can do this in a view hook:

function mymodule_views_pre_view($view, $display_id, array &$args) {
  if ($view->id() == 'my_custom_data_view') {
    $view->element['#cache']['tags'][] = 'custom-data-list`;
  }
}

or use the module Views Custom Cache Tags.

By this all cache entries that contain the View, for example blocks or pages and the view itself are tagged with this tag.

Now the only thing you have to do, whenever you change the data in the database (this is for all CRUD operations, that write to the database), invoke:

\Drupal\Core\Cache\Cache::invalidateTags(['custom-data-list']);


LDAP + Workbench or LDAP + OG I have come to an impasse in the development.

MY GOAL:
Setup department pages on the site, giving editing access to specific LDAP roles
Creating workflow for the data(draft,review,publish).
Creating private content for department users.

My Solution(SO FAR):

I have the LDAP module install on our D7 site.  I am mapping LDAP fields to the profiles and roles, Using LDAP queries with a view to display a "staff" page.

I have tinkered around with OG, Workbench, Workflow, TAC and TAC_lite. SO FAR NONE really meet the control and goals we have set out to obtain.

I am hoping that there is someone out here that has conquered a similar setup and could impart some of their wisdom on me.

All constructive thoughts will be appreciated

Well after much trial and error  which included rebuilding permissions more times that I want to count. I came up with a solution based on the following link:

http://drupal.org/node/200631

A combination of Taxononmy Access Control and Taxonomy on content type, which allows for a almost module-less solution.

Hope this helps someone else.


How can I make downloads available only to authenticated users? With Drupal 7, I created a content type with a field to attach files. I am using private file uploads. When viewing the node, the list of attached files is visible to every user, including anonymous users.

I want that logged-in users are able to click on a file link to download the files attached to nodes; anonymous users should be able to see the list of files, but clicking on a file link should show them the login page, forcing them to log in, and them download the attached files.

How can I achieve this?

You can try Private Files download permission module for drupal 7 and you can set permission to download to certain users.


How can I watermark images with a taxonomy term from the node they belong to? I'm working on a site for a business who would like to watermark all their product photos with the brand name of the product (which is a taxonomy term reference field on the product content type).
Looking into this, I found a variety of modules that will watermark images in various ways, but most expect to just put a single image or text overlay on all images of a given style, which is not what I need here.
The one exception I found was Textimage, which works with the Image Effects module and, at least in theory, supports node tokens. But when I tried out those two modules, I was unable to get any token for the taxonomy field in question to work. I tried [node:field_brand] and [node:field_brand:entity:name] without success — it just put the text of the token instead of replacing it with the brand. Other tokens, like [node:title], did work, but not the one I wanted (even though it was in the list of available tokens).
I posted to the issues queue for Textimage, but it doesn't seem like anyone's monitoring it regularly, and I'm on a deadline.
Does anyone know either how I can get the node replacement to work in Textimage, or alternatively any other way of doing this? I'm not at all wedded to Textimage and Image Effects — they're just the only modules thus far that claim to be able to do what I need to do.

Problem solved — Rainer Feike's comment prompted me to examine the field setup and I realized I had made an error in the way I set it up that was causing the token not to resolve (there were two taxonomy fields on the original product content type, referencing two different vocabularies, and I had matched the wrong field name with the vocabulary in setting up the test content type I was trying out the new image style on).
Once I corrected that it worked. My apologies for posting about what turned out to be a self-created problem.


Block not showing on page I have a weird issue with a D6 site... A block I've created will not show up on the page. It appears to be disabled in the blocks list, although other blocks that /are/ showing up seem to be disabled as well. When I try to move it to a region, it jumps back to 'disabled' region.

Has anyone run into this issue and found a solution? Any help would be much appreciated!

Likely a different module is being used to control block display: Context or Panels would be the most likely options.  It's possible someone wrote a custom module to disable blocks in the standard blocks interface to force you away from it.

Note: Drupal 6 is no longer officially supported by the community. While there are some places that are offering long term support for Drupal 6, you should plan to move to Drupal 7 or 8 soon.


How to 'Entity Reference' using Rules I am simply trying to autopopulate a Taxonomy Term from Content Type A into Content Type B.

An example, I'm creating a review site for Cars:

Content Type A = Car Model
field: field_car_model_tag

Content Type B = Car Review
field: field_car_review_tag

Assuming, Content Type A|CAR MODEL has already been created, titled "FORD MODEL".... My users will find and click a "Review Ford" link that routes them to Content Type B|CAR REVIEW, and auto-populates the Node Reference field (Node Reference URL Widget, for example, even though I'm attempting to only use Entity Reference fields).

After saving this same Content Type B|CAR REVIEW node, I would like this field, 'field_car_review_tag' to automatically populate with it's sister term from Content Type A|CAR MODEL.

In Drupal 6 Rules, I found this to be very straightforward.
I would simply "Load a referenced node, and then set a CCK field without validation", applying the token from the referenced content type.  In Drupal 7, the settings are seemingly endless.

Thank you for your help!

I believe I've resolved this issue; least it looks good so far.  Super thanks to Alauddin's response to "how to create rules to send email notification for node reference content?"

EVENT
After saving new content of Car Review

CONDITION

Entity has field
data selector: node:field-car-review-node-reference
value: field_car_model_tag

ACTION

Fetch Entity by ID, with value: node and data selector: node:field-car-review-node-reference:nid
Set a data value, with selected data (that I want to change): node:field-car-review-node-reference:field-car-model-tag

I think I have this right, here is an export of my Rule:

{ "rules_term_ref_4" : {
"LABEL" : "TERM REF 4",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules" ],
"ON" : {
  "node_insert--car_review" : { "bundle" : "car_review" },
  "node_update--car_review" : { "bundle" : "car_review" }
},
"IF" : [
  { "entity_has_field" : {
      "entity" : [ "node:field-car-review-node-reference" ],
      "field" : "field_car_model_tag"
    }
  }
],
"DO" : [
  { "entity_fetch" : {
      "USING" : { "type" : "node", "id" : [ "node:field-car-review-node-reference:nid" ] },
      "PROVIDE" : { "entity_fetched" : { "entity_fetched" : "Fetched entity" } }
    }
  },
  { "data_set" : {
      "data" : [ "node:field-car-review-tag" ],
      "value" : [ "node:field-car-review-node-reference:field-car-model-tag" ]
    }
  }
]
}
}


Creating a Rule for email recipients I am working on a site that has a registration form (created with Webform) for 4 different conferences.

The registration goes to everyone on the list (there are 8 people on the email list). But we just added another conference that should only go to 3 people in particular.

Is there a way, to write a rule (we have custom ruleset module) to have the registration email for a particular conference go to a specific person?  I am working on Drupal 7.

Any suggestions would be greatly appreciated.

There doesn't seem to be a "custom ruleset" module on Drupal.org, but I'd simply use the Rules module, together with the Webform Rules module, as further explained below.

Step 1 - Create a basic eMail about the submitted Webform

Have a look at this example rule (in Rules export format):

{ "rules_process_submitted_webform" : {
    "LABEL" : "Process submitted webform",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "webform_rules" ],
    "ON" : { "webform_rules_submit" : [] },
    "IF" : [
      { "data_is" : { "data" : [ "form-id" ], "value" : "2" } },
      { "user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "2" : "2" } }
        }
      }
    ],
    "DO" : [
      { "mail" : {
          "to" : "[site:mail]",
          "subject" : "A new webform submission has occured",
          "message" : "A new webform submission has occured (with form-id \u0022[form-id:value]\u0022). It was submitted by the user with id = [user:id], name = [user:name] and eMail Id = [user:mail] ...",
          "language" : [ "" ]
        }
      }
    ]
  }
}

Some details about the above rule:

Rules Event: After a webform has been submitted
Rules Conditions:

Form-id has value "2" (change to whatever form-id to fit your case).
User submitting the form is logged in.

Rules Action: Sent an eMail.

Not sure if it is the case for you, but if the user who submitted the form is authenticated (not anonymous), then you do already have access to a limited set of tokens related to the user who submitted the webform, such as [user:id], [user:name] and [user:mail]. If the user is anonymous, just omit that condition, and don't refer to those tokens in the eMail being created.

Step 2 - Include data from the submitted Webform data in your eMail

You do have access to all labels and all values of any field of a Webform, ie:

[data:MachineFieldName-title] contains the Label of a field with machine name MachineFieldName.
[data:MachineFieldName-value] contains the Value of a field with machine name MachineFieldName

For way more details on this, and a prototype rule about this, refer to the answer to "How to create a node from a Webform using rules?":

the 1st attempt relates to using "Entity has field" (which doesn't work for Webform).
the 2nd attempt explains what to do in case of Webform.

And while the above is a good start, it may still not be sufficient to achieve your goal. I.e. if you want to use specific data from the submitted webform. However, you can use a technique similar to what is described in my answer to "How to do a data comparison to submitted webform data when using the Rules module?". For short:

Add an extra Rules Action to Add a variable, with a value assigned to it equal to your [data:SomeField-value-raw] (and with an appropriate data type). I'm assuming a field in your webform has a machine name like SomeField (adapt to fit your machine name).
In your subsequent Rules Actions you can refer to the value of this variable you just added (that's the clue!).

Step 3 - Cover all possible variations of the Webform data

To make this work for each of the 4 (or 5?) conferences, you basically have 2 options:

Duplicate this rule for each possible form id (or form component value if all conferences are covered via a single form) you want to process this way. E.g 1 such rule for each conference.
Use the Conditional Rules module if you want to have a single (consolidated) rule for all conferences to be processed.

Here is an example rule (in Rules export format), which uses the Conditional Rules module:

{ "rules_process_submitted_webform_based_on_a_component_value" : {
    "LABEL" : "Process submitted webform based on a component value",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_conditional", "webform_rules" ],
    "ON" : { "webform_rules_submit" : [] },
    "IF" : [
      { "data_is" : { "data" : [ "form-id" ], "value" : "2" } }
    ],
    "DO" : [
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:somefield-value-raw]" },
          "PROVIDE" : { "variable_added" : { "submitted_form_component_value" : "Submitted form component value" } }
        }
      },
      { "SWITCH" : {
          "USING" : { "data" : [ "submitted-form-component-value" ] },
          "DO" : [
            { "CASE" : {
                "USING" : { "value" : "1" },
                "DO" : [ { "drupal_message" : { "message" : "Webform Option 1 was selected" } } ]
              }
            },
            { "CASE" : {
                "USING" : { "value" : "2" },
                "DO" : [ { "drupal_message" : { "message" : "Webform Option 2 was selected" } } ]
              }
            },
            { "CASE" : {
                "USING" : { "value" : "3" },
                "DO" : [ { "drupal_message" : { "message" : "Webform Option 3 was selected" } } ]
              }
            },
            { "DEFAULT CASE" : [
                { "drupal_message" : { "message" : "Webform Option selected was different from 1, 2 and 3" } }
              ]
            }
          ]
        }
      }
    ]
  }
}

Some details about the above rule:

Rules Event: After a webform has been submitted
Rules Condition: Form-id has value "2" (change to whatever form-id to fit your case).
Rules Actions:

Add an extra Rules Action to Add a variable, with a value assigned to it equal to your [data:SomeField-value-raw] (and with an appropriate data type). I'm assuming a field in your webform has a machine name like SomeField (adapt to fit your machine name).
Show a message on the site (depending on the value of the variable that was added via the prior Rules Action).

What is left to do to further tune the above Rules example to fit your needs:

Replace the "Show a message on a site" by an appropriate eMail to be created (for each "case").
And for each of those eMails just indicate which eMail Ids should receive that eMail.

Voilà

PS: forget about your "custom ruleset module", no more need for it to solve this challenge.


User registration form at a new menu path got error after submit I'm creating an employee directory. I created a menu path which renders user registration form with profile fields.
When I submit the form, I got some unknown errors. I did fill out every fields in the form, but drupal shows "required" errors.

  Error
  The website encountered an unexpected error. Please try again later.

  Password field is required.
  You must enter a username.
  You must enter an e-mail address.
  Notice: Undefined index: array_parents in field_default_form_errors() (line 369 of
  D:\fakepath\testsite\modules\field\field.form.inc).
  Recoverable fatal error: Argument 2 passed to drupal_array_get_nested_value() must be an array, null given, called
  in D:\fakepath\testsite\modules\field\field.form.inc on line 369 and
  defined in drupal_array_get_nested_value() (line 6490 of
  D:\fakepath\testsite\includes\common.inc).

I have hook_form_alter in which some fields are made hidden.
Here is my code snippet in my custom module.

<?php
/*
 * Implementation of hook_menu()
 */
function mymodule_menu(){
    $items['employee/create'] = array(
        'title' => t('Create Directory'),
        'page callback' => 'drupal_get_form',
        'access callback' => 'mymodule_access_directory',
        'page arguments' => array('mymodule_employee_create_form'),
        'type' => MENU_NORMAL_ITEM,
        'weight' => 0,
    );
    return $items;
}
/*
 * Implementation of access callback for the menu
 */
function mymodule_access_directory(){
    global $user;
    # administrator can only access this
    if( in_array('administrator', $user->roles) ){
        return TRUE;
    }
    return FALSE;
}
/**
 * Home page which shows latest entered ten legs with cheapest tickets
 */
function mymodule_employee_create_form(){
    drupal_set_title('Create Employee Directory');
    return drupal_get_form('user_register_form');
}

/**
 * Implementation of hook_form_alter
 * Override form structure
*/
function mymodule_form_alter(&$form, &$form_state, $form_id) {

    if($form_id == 'user_register_form'){
        if($_GET['q'] == 'employee/create'){ # admin only can access this page
            # hide drupal default role selection; default role is employee
            $form['account']['roles']['#default_value'] = array(6);
            _mymodule_hide_elem($form, 'roles', 'account');
            # hide auto assign role selection; default role is employee
            $form['autoassignrole_user']['user_roles']['#default_value'] = 6;
            _mymodule_hide_elem($form, 'autoassignrole_user');
            # hide Status
            _mymodule_hide_elem($form, 'status', 'account');
            # hide Notify
            _mymodule_hide_elem($form, 'notify', 'account');

            # Change "Create new account" to "Create"
            $form['actions']['submit']['#value'] = 'Create';
        }

    }
}

function _mymodule_hide_elem(&$form, $name, $group=NULL){
    if($group){
        $form[$group][$name]['#prefix']     = '
';
        $form[$group][$name]['#suffix']     = '
';
        $form[$group][$name]['#required']   = FALSE;
    }else{
        $form[$name]['#prefix']     = '
';
        $form[$name]['#suffix']     = '
';
        $form[$name]['#required']   = FALSE;
    }
}
?>

My mistake in my hook_menu(). The page arguments should be array('user_registration_form') and I removed the custom page callback mymodule_employee_create_form(). It did work as expected.

function mymodule_menu(){
    $items['employee/create'] = array(
        'title' => t('Create Directory'),
        'page callback' => 'drupal_get_form',
        'page arguments' => array('user_register_form'),
        'access callback' => 'mymodule_access_directory',
        'type' => MENU_NORMAL_ITEM,
        'weight' => 0,
    );
    return $items;
}


Edit Drupal Form in "popup" just like it is done in Drupal Views Edit form I am making replica of views module. We when navigate to view in admin/list/structure, we add new view. Here we type name of our view and content type. After clicking "save and continue", it is redirected to view edit page.

On the top, there is,
Title
title:None
And when we click on "None", a popup box will appear to edit title of the view and replaces "None" with the title given by us.

I need to have this edit in popup functionality. Can anyone please help doing it.

I think what you are looking for is the ctools modal functionality.
Without further digging into that - because I think the following tutorial is comprehensive, easy to understand and complete - here is a link that will help you: https://www.deeson.co.uk/labs/insert-form-pop-modal-ctools-and-drupal-7

Some important things you should not forget:

Add the ctools module as dependency.
Add the callback to the menu.
Include the ctools js files on the page where the link to the title popup is.

ctools modal helped me a lot! Give it a try!


What reasons are there for views not rendering a link? The link passes the nid and date to another view. List of classes presenting a link to a list of bookings.

In the following example John's class has a link but Jake's class does not.

The 'Add booking' and 'Claim' links work for all classes and pass the url as nid/time where time is in seconds rather than formatted to be passed to views.

The date field is setup with the date formatted as follows

The link is created through rewriting

More things that don't work.

Turn off Style settings > "add default classes"
Just rewrite the text instead of "Output this field as a link". I get the half closed span. This is true if I rewrite the source field.

2017-09-26AEST14:35">View Bookings
Creating a plain text field and rewriting there. Same result as for rewriting inline.

I can see why taking the default classes away might work, as it might stop the date formatter wrapping the text.
The link formatter looks like it is removing the span, so any other rewriting doesn't work.

This works if you set up a source field:

Create a source field with the date formatting.
Rewrite the output of the field with just the tag. [date_when_2] in my case.
Select "Strip HTML tags".

Then create a custom text field that rewrites the output as the link.