Views aggregation, sum of node count in _each row_ I have a View that uses aggregation to count the number of nodes of a custom color type. For example, there are 10 red nodes, 10 green nodes and 20 blue nodes. For each color, I would want it's node count and the total count to show up on each row, like this:

Color    Count   Total
Red       10      40
Green     10      40
Blue      20      40

Ultimately, I do want to calculate the percentage in each row as well, but for now I'd just like the total.

What's the most efficient "drupal" way of doing this?

A no-custom-code solution could be something like this (not the most performant way though but you could perhaps do something with views caching).

Explanation:
Create one view for the total count that with the use of aggregration and a content type filter returns the total number of nodes (the Total column)
In another Taxonomy Terms view you attach the total count view by adding a Global: View field that is provided by the Views Field View module

Steps
 - Create a content type e.g. "Colornode"
 - Create a taxonomy vocabulary called "Colors"
 - Add three terms Blue,Green and Red
 - Add a term reference field and select Colors as the vocabulary
 - Install and enable the Views Field View  module

Then import these two views in this order:

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

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Node counts';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['group_by'] = TRUE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['query']['options']['query_comment'] = FALSE;
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'none';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['style_options']['default_row_class'] = FALSE;
$handler->display->display_options['style_options']['row_class_special'] = FALSE;
$handler->display->display_options['row_plugin'] = 'fields';
$handler->display->display_options['row_options']['inline'] = array(
  'type_1' => 'type_1',
  'type' => 'type',
);
$handler->display->display_options['row_options']['separator'] = ': ';
/* Field: Content: Type */
$handler->display->display_options['fields']['type_1']['id'] = 'type_1';
$handler->display->display_options['fields']['type_1']['table'] = 'node';
$handler->display->display_options['fields']['type_1']['field'] = 'type';
$handler->display->display_options['fields']['type_1']['label'] = '';
$handler->display->display_options['fields']['type_1']['exclude'] = TRUE;
$handler->display->display_options['fields']['type_1']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['type_1']['element_default_classes'] = FALSE;
/* Field: COUNT(Content: Type) */
$handler->display->display_options['fields']['type']['id'] = 'type';
$handler->display->display_options['fields']['type']['table'] = 'node';
$handler->display->display_options['fields']['type']['field'] = 'type';
$handler->display->display_options['fields']['type']['group_type'] = 'count';
$handler->display->display_options['fields']['type']['label'] = '';
$handler->display->display_options['fields']['type']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['type']['element_default_classes'] = FALSE;
$handler->display->display_options['fields']['type']['separator'] = '';
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'colornode' => 'colornode',
);

/* Display: Block */
$handler = $view->new_display('block', 'Block', 'block');

And the second one:

$view = new view();
$view->name = 'colorterms';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'taxonomy_term_data';
$view->human_name = 'Color terms';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Color terms';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['group_by'] = TRUE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '100';
$handler->display->display_options['style_plugin'] = 'table';
/* Relationship: Taxonomy term: Content using Color */
$handler->display->display_options['relationships']['reverse_field_color_node']['id'] = 'reverse_field_color_node';
$handler->display->display_options['relationships']['reverse_field_color_node']['table'] = 'taxonomy_term_data';
$handler->display->display_options['relationships']['reverse_field_color_node']['field'] = 'reverse_field_color_node';
/* Relationship: Content: Color (field_color) */
$handler->display->display_options['relationships']['field_color_tid']['id'] = 'field_color_tid';
$handler->display->display_options['relationships']['field_color_tid']['table'] = 'field_data_field_color';
$handler->display->display_options['relationships']['field_color_tid']['field'] = 'field_color_tid';
$handler->display->display_options['relationships']['field_color_tid']['relationship'] = 'reverse_field_color_node';
/* Field: Taxonomy term: Name */
$handler->display->display_options['fields']['name']['id'] = 'name';
$handler->display->display_options['fields']['name']['table'] = 'taxonomy_term_data';
$handler->display->display_options['fields']['name']['field'] = 'name';
$handler->display->display_options['fields']['name']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['name']['alter']['ellipsis'] = FALSE;
$handler->display->display_options['fields']['name']['link_to_taxonomy'] = TRUE;
/* Field: COUNT(Content: Color) */
$handler->display->display_options['fields']['field_color']['id'] = 'field_color';
$handler->display->display_options['fields']['field_color']['table'] = 'field_data_field_color';
$handler->display->display_options['fields']['field_color']['field'] = 'field_color';
$handler->display->display_options['fields']['field_color']['relationship'] = 'reverse_field_color_node';
$handler->display->display_options['fields']['field_color']['group_type'] = 'count';
$handler->display->display_options['fields']['field_color']['label'] = 'Count';
$handler->display->display_options['fields']['field_color']['separator'] = ', ';
/* Field: Global: View */
$handler->display->display_options['fields']['view']['id'] = 'view';
$handler->display->display_options['fields']['view']['table'] = 'views';
$handler->display->display_options['fields']['view']['field'] = 'view';
$handler->display->display_options['fields']['view']['label'] = 'Total';
$handler->display->display_options['fields']['view']['view'] = 'nodecounts';
$handler->display->display_options['fields']['view']['display'] = 'block';
/* Filter criterion: Taxonomy vocabulary: Machine name */
$handler->display->display_options['filters']['machine_name']['id'] = 'machine_name';
$handler->display->display_options['filters']['machine_name']['table'] = 'taxonomy_vocabulary';
$handler->display->display_options['filters']['machine_name']['field'] = 'machine_name';
$handler->display->display_options['filters']['machine_name']['value'] = array(
  'colors' => 'colors',
);
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['relationship'] = 'reverse_field_color_node';
$handler->display->display_options['filters']['type']['value'] = array(
  'colornode' => 'colornode',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'color-terms';
$handler->display->display_options['menu']['type'] = 'normal';
$handler->display->display_options['menu']['title'] = 'Color terms';
$handler->display->display_options['menu']['name'] = 'main-menu';

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page_1');
$handler->display->display_options['path'] = 'color-terms';
$handler->display->display_options['menu']['type'] = 'normal';
$handler->display->display_options['menu']['title'] = 'Color terms';
$handler->display->display_options['menu']['name'] = 'main-menu';

Result


How to print date in image in Event List in Drupal How can I print a date like JAN 28 in the provided Event list, using Drupal Views?

The example image taken from the Drupal website is attached below

Navigate to /admin/config/regional/date-time/formats/add and add a new date format. For the replacement pattern use: M t then click save.

then navigate to: /admin/config/regional/date-time and create a human readable name for your custom date format, then select the date format you created inside the select box. click save.

Create your view add your date field and then in the field settings give it your custom date format for the format section.

Style with CSS. You're done.

You may need to create two different date formats to achieve the styling you want. One for M and one for t. Then add your date field to the view twice and add the date formats on the fields, then you can easily target the two different date elements and use css to position them the way they are in the image you provided.


Which hook to implement to limit node creation? I'm looking to limit the number of nodes that a user can create in Drupal 7.

Which hook should I implement to step in before the 'add node' page is shown?

Alter the access callback for the menu callback:

function custom_module_menu_alter(&$items){
    $items['node/add/page']['access callback'] = 'my_custom_access_callback';
    // Next line needed for Drupal 7
    unset($items['node/add/page']['access arguments']);
}

Add a function as your custom access callback:

function my_custom_access_callback() {
   global $user;
   $allowed_limit = variable_get('allowed_limit', 10);

   // If Drupal 6.
   $node_counts = db_result(db_query("SELECT count(*) FROM {node} WHERE uid = %d;", $user->uid));
   // End If

   // If Drupal 7.
   $node_counts = db_query("SELECT count(*) FROM {node} WHERE uid = :uid", array(':uid' => $user->uid))->fetchField();
   // End If

   if ($node_counts < $allowed_limit && user_access("create page")) {
     return TRUE;
   }
   else{
     drupal_set_message(t('Print message about exceeded limit and/or user permissions.'));
     return FALSE;
   }
}

This kind of logic will restrict a user to exceed the limit.


How can I allow admins to choose anything from an Entity Reference field while restricting it for everyone else? I'm doing a job listings site. Users with privileges to list jobs have an Entity Reference field connecting them to a Company node. Job nodes have a similar field. So when an employer creates a Job, he should only be able to choose the Company in his own ER field.

This much I can do: I just created an Entity Reference View and limited it with a Referencing Entity Relationship and a Current User filter that uses that Relationship.

However, admins should be able to create Jobs for any Company. This is where I fall down. It seems like there's nothing I can do inside this View, since everything in this View has to do with the nodes being listed; there's no way to conditionally turn off a filter based on the current user.

So now I need other options. I see the obvious workaround: Make the User Company field accept multiple values, and give every single one to every admin user. That will be my last resort. Before I give up and go that route, does anyone have any ideas? Any answer will do, though if yours requires my admin users to grant themselves new permissions every time we create a company, I will probably disregard it. Thanks!

The solution was to use hook_views_pre_build. That hook lets you edit the view's criteria before it actually gets run. Here's my full code:

function mymodule_permission() { // Create the permission for privileged users
    return array(
        'create jobs for any company' => array(
            'title' => t('Create Jobs for any Company'),
            'description' => t("Don't limit the Company field in the Job node type to only those Companies assigned to the user."),
        ),
    );
}

function mymodule_views_pre_build(&$view) {
    /* If it's the right view and the user has the above permission… */
    if($view->name === 'job_company_entity_reference' && user_access('create jobs for any company')) {
        /* …then get rid of the view criteria that limit the choices for everyone else.
        (I found these by enabling the devel module and calling dpm($view) at the top of this function.) */
        unset($view->filter['uid_current']);
        unset($view->relationship['reverse_field_company_user']);
    }
}


Uploading Image to s3 turns to horizontal always I am using s3fs module to put images on s3bucket using image field in any content type.

When I take a verticle picture, upload it to the s3bucket, it turns to horizontal.
On local file system, it works fine, but not on s3. Any idea what could be the reason?

Without knowing the origin of your images nor the s3f module I'm rather guessing  your problem consists of the two following parts:

the EXIF data of your images probably contains information that says 'this image should be displayed horizontally
the s3fs module or actually drupal's image module respects the information about the image orientation – but that's different from your expectation (could also be that the problem is that the info about the orientation is not respected)

According to this I would suggest you try either (or both) of the following:

try to strip the EXIF data in case you don't need it, for example by saving "websafe" from Photoshop or the like
Try to 'teach' drupal the correct exif orientation – for example by using the EXIF Orientation module.


A Drupalogical question about Slider captions Take a Slider module, no matter which one of them. If a Caption is based on a Body field, and There are many images and only one body field, How would you make different captions per every image?...

Thanks,

Using the Media module, you can add fields to images, such as description or caption. https://drupal.org/project/media

Alternatively, you could use the Field collection module to create a 'Gallery image' field type, which has the extra fields that you need.


Extract PDF front page and store it as an image field in node I'm using Document Library module to manage my files and create listings for them.

I've also noticed the existence of PDFPreview module and I'd like to ask if the following is possible:

I'd like to upload a pdf file in a Document Library Document item and with this file to generate an preview image, stored as a new independent field (lets say the Thumbnail image field) in this content type. As things are now the preview replaces the file field which is something that I need to avoid.

Oh I just realized that another module, the PDF to Image Field module does exactly what I need! Some more details about thsi module (from its project page):

The PDF To ImageField module provides automatic conversion of uploaded PDF files to images. It can be used either to create a snapshot of the front page to use as a preview thumbnail, or to generate a gallery of images from each page in the document.
The module is implemented as an additional widget for File Field where PDFs are uploaded to. It places generated images into a Image Field on the same content type.

At least, I hope this helps other people too.


Hide body on node edit if user can't access input format The default behaviour is that a user can't edit a node when they don't have access to its current input format, even if they do have the edit content type permission. I'd like to just hide the body field in those situations. Does anyone know of a contrib that does that? (I'm only interested in the body field, but a more general solution would be cool too.)

Not really an answer, but there is AFAIK no way to change this without hacking core.

The check for this is directly in node_access() and can't be altered.

What you are trying to do is btw how it works in Drupal 7, see the corresponding issue.


@font-your-face don't work when 'Aggregate and compress CSS files' is enabled I added font using @font-your-face module and everything works just fine except when 'Aggregate and compress CSS files' is enabled. When I enable css aggregation and compression, whole website use some default font instead imported font in @font-your-face.

Does anyone have problem like this? Some suggestions how to resolve this?

After your compress the CSS using Aggregate option in Drupal, viewing the source code you'll find that there is an syntax error for @font-face.

Check for your syntax, there would be a break-age in that while aggregation.


Redirect the page after login with using modal form I want to redirect the page after user login. for login i have using modal form.  I already use the Login designation module but its not working.
Any idea how do this?

Add this in your custom module. Hope it works.

/**
 * Implements hook_user_login().
 */
function my_module_user_login(&$edit, $account) {
ctools_add_js('ajax-responder');
$commands = array();
$commands[] = ctools_ajax_command_redirect('YOUR-REDIRECT-PAGE');
print ajax_render($commands);
exit;
}


Access front page node only by front page link I have a problem with front page node redirection. I have created a node which I want to be a front page (let's say it's path is node/6). I have also set "Default front page" path with path of my node. The problem is that my node is accessible by two links now:

http://example.com/
http://example.com/node/6

How can I make my node to be accessible only by front page link?

Assuming you want http://example.com/node/6 to redirect to http://example.com/, I'd take a look at the global redirect module: http://drupal.org/project/globalredirect


How to use prepareKey() for the Migrate module I am trying to do write a migration class extending the Migrate module. The migration will be from an XML file so I will want to extend the XMLMigration class. Based on the Migrate modules wine.inc example, I'm going to have to something like this:

class WineProducerXMLPullMigration extends XMLMigration {
 public function __construct($arguments) {
  ....
  $item_xpath = '/producers/producer';  // relative to document
  $item_ID_xpath = 'sourceid';          // relative to item_xpath

  $this->source = new MigrateSourceXML($items_url, $item_xpath,
                                       $item_ID_xpath, $fields);
  }
}

My issue is that my xml doesn't have any unique ID per row, and therefore I can't really pass a $item_ID_path. I read this post https://www.drupal.org/node/1444356#comment-6974360 and found that the prepareKey() function is supposed to be used for this purpose, however as far as I can tell, you don't ever call this directly, and its called after this class is finished processing. This being the case, I'm not sure what I should be passing in $item_ID_xpath and it is a required field.

You can set the $item_ID_xpath to something that does exist in the XML, for example 'name'

Then inside your migration class, you can use the prepareKey method to generate an ID

public function prepareKey($source_key, $row) {
  $row->glid = crc32($row->xml->name);
  $key['glid'] = $row->glid;
  return $key;
}

I am using crc32() to generate an ID from a string, but I have no clue whether that is smart or not, so use at own risk.

Now that you have an ID ('glid' in the example) you use in the mapping:

$this->map = new MigrateSQLMap($this->machineName, array(
  'glid' => array(
    'type' => 'varchar',
    'length' => '255',
    'not null' => TRUE,
    'description' => 'id generated from a string'
  ),
), MigrateDestinationNode::getKeySchema()
);

Dont forget to deregister the migration if you change this schema.


After enabling utf8mb4 on 7.50, cannot enable update module I upgraded to 7.50, ran the utf8mb4 convert drush commmand, and enabled utf8mb4 in settings.php.  Before running the utf8mb4 convert drush command, I did have to convert several columns manually like this:

ALTER TABLE commerce_order CHANGE order_number order_number VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

I tested my site and as far as I can tell everything is working fine.

However, when I try to enable the update module (which had been uninstalled on the site), I get the following error:

cpu:update pk$ drush @mysite en update
PTY allocation request failed on channel 0
The following extensions will be enabled: update
Do you really want to continue? (y/n): y
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1071    [error]
Specified key was too long; max key length is 767 bytes in
/srv/bindings/d767913ee30941f3847c9361d2d787ba/code/includes/database/database.inc:2204
Stack trace:
#0
/srv/bindings/d767913ee30941f3847c9361d2d787ba/code/includes/database/database.inc(2204):
PDOStatement->execute(Array)
#1
/srv/bindings/d767913ee30941f3847c9361d2d787ba/code/includes/database/database.inc(683):
DatabaseStatementBase->execute(Array, Array)
#2
/srv/bindings/d767913ee30941f3847c9361d2d787ba/code/includes/database/schema.inc(664):
DatabaseConnection->query('CREATE TABLE {c...')
#3
/srv/bindings/d767913ee30941f3847c9361d2d787ba/code/includes/database/database.inc(2753):
DatabaseSchema->createTable('cache_update', Array)
#4
/srv/bindings/d767913ee30941f3847c9361d2d787ba/code/includes/common.inc(7109):
db_create_table('cache_update', Array)
#5
/srv/bindings/d767913ee30941f3847c9361d2d787ba/code/includes/module.inc(479):
drupal_install_schema('update')
#6 /opt/pantheon/drush-8/commands/core/drupal/environment_7.inc(143):
module_enable(Array)
#7 /opt/pantheon/drush-8/commands/pm/pm.drush.inc(1167):
drush_module_enable(Array)
#8 /opt/pantheon/drush-8/includes/command.inc(366):
drush_pm_enable('update')
#9 /opt/pantheon/drush-8/includes/command.inc(217):
_drush_invoke_hooks(Array, Array)
#10 /opt/pantheon/drush-8/includes/command.inc(185):
drush_command('update')
#11 /opt/pantheon/drush-8/lib/Drush/Boot/BaseBoot.php(67):
drush_dispatch(Array)
#12 /opt/pantheon/drush-8/includes/preflight.inc(66):
Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#13 /opt/pantheon/drush-8/drush.php(12): drush_main()
#14 {main}

When I enable the update module, it isn't able to create the update or cache_update tables.  How can I fix this?

Hacking core, not a great answer.  This is just the best I have found so far.

In modules/update/update.install:

/**
 * Implements hook_schema().
 */
function update_schema() {
  $schema['cache_update'] = drupal_get_schema_unprocessed('system', 'cache');
  $schema['cache_update']['description'] = 'Cache table for the Update module to store information about available releases, fetched from central server.';
  return $schema;
}

So I went to modules/system/system.install:

  $schema['cache'] = array(
    'description' => 'Generic cache table for caching things not separated out into their own tables. Contributed modules may also use this to store cached items.',
    'fields' => array(
      'cid' => array(
        'description' => 'Primary Key: Unique cache ID.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'data' => array(
        'description' => 'A collection of data to cache.',
        'type' => 'blob',
        'not null' => FALSE,
        'size' => 'big',
      ),
      'expire' => array(
        'description' => 'A Unix timestamp indicating when the cache entry should expire, or 0 for never.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'created' => array(
        'description' => 'A Unix timestamp indicating when the cache entry was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'serialized' => array(
        'description' => 'A flag to indicate whether content is serialized (1) or not (0).',
        'type' => 'int',
        'size' => 'small',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'expire' => array('expire'),
    ),
    'primary key' => array('cid'),
  );

And I changed the length of the varchar for the primary key from 255 to 191.  Now I can enable and disable the update module properly.


Problem with Drupal 7 file permissions I set up a working Drupal 7 installation on somebody else's server and the image generation only worked if all folders leading to the thumbnail folder were given 777 permission.

This must be a an Apache configuration issue - has anybody else come across this?

You need to go to your drupal installation root folder and type the following

chown -R user:www-data .
find . -type d -exec chmod u=rwx,g=rx,o= {} \;
find . -type f -exec chmod u=rw,g=r,o= {} \;

where www-data type the user under which apache/http process runs

Then go at sites/ directory and type the following

find . -type d -name files -exec chmod ug=rwx,o= '{}' \;
find . -name files -type d -exec find '{}' -type f \; | while read FILE; do chmod ug=rw,o= "$FILE"; done
find . -name files -type d -exec find '{}' -type d \; | while read DIR; do chmod ug=rwx,o= "$DIR"; done

See http://drupal.org/node/244924 for more information.


How to check if managed_file has uploaded a video and use it in states I want to disable the submit button in a form for as long as there are no value/uploaded video in a managed_file but I can't seem to find what form name or element property I have to check for in #states.
I have the following:
$form['file'] = [
  '#type' => 'managed_file',
  '#title' => t('File'),
  '#description' => $this->t('Choose video to upload.'),
  '#upload_validators' => $validators,
];
$form["submit"] = [
  "#type" => "submit",
  "#value" => t('Submit'),
  '#states' => [
    'enabled' => [
      ':input[name="file"]' => ['empty' => FALSE],
    ],
  ],
];

I've also tried using value => true, :input[name="files[0] and :input[name="files[file] without luck. How can I enable the submit button when file has been processed?

If you examine the comments in the documentation, there are several things to look out for:

You may need to target the element's widget, as mentioned in this comment. Most likely you would do this in a #process callback or in a form alter hook.

This is a good nuance to understand - thanks! Targeting the widget
worked for me on a number field. It gets ignored otherwise.

// My number field is hidden unless repeat is selected
$form['field_myfield_num']['#states'] = [
  'visible' => [
    ':input[name="field_myfield_select"]' => ['value' => (string) 'repeat'],
    ],
];

// My number field is set as required when repeat is selected.
$form['field_myfield_num']['widget']['0']['value']['#states'] = [
  'required' => [
    ':input[name="field_myfield_select"]' => ['value' =>  (string) 'repeat'],
  ],
];

In the same comment above, we also see that sometimes it helps to cast your candidate value to a string: ['value' =>  (string) 'repeat']. I've also seen this explicitly mentioned elsewhere, but can't find the reference.

It is possible to test for a negation using '!value', as seen in this comment:

I had a form with a field of #type select_or_other, which renders like
radios. I wanted to enable the submit button when the form element was
not "none". The following worked for me:

$form['actions']['submit'] = [
  '#type' => 'submit',
  '#value' => $this->t('Donate'),
  '#button_type' => 'primary',
  '#states' => [
    'enabled' => [
      ':input[name="amount[select]"]' => ['!value' => 'none'],
    ],
  ],


Policy Question: Can I Use a Submodule that Does Not Follow Drupal Code Guidelines? I have a fairly extensive plugin system that I wrote.

It uses an MVVM pattern, where the lions' share of the code is in a cross-CMS class.

I haven't submitted the Drupal plugin to the Drupal repo, because it does not follow their coding conventions.

It has extremely rigorous coding conventions; just not the ones prescribed by Drupal.

Fair enough. They have every right to dictate coding standards. That's a good idea, and I support it.

However, I can't rewrite the MVVM library to make just one of the targets happy.

Since the MVVM library is actually a submodule, can I submit the plugin to the Drupal repository if the Drupal-specific parts (just a couple of files) are set up to use Drupal standards?

For that matter, since Git is so horrible with submodules, I wonder if the Drupal repository can even handle submodules.

Since the MVVM library is actually a submodule, can I submit the plugin to the Drupal repository if the Drupal-specific parts (just a couple of files) are set up to use Drupal standards?

Yes, as long as your Drupal project conforms to the GIT repo policy - where just one of terms are: "All code should comply to the coding standards." you can commit it (such projects are known as "bridge modules") to the Drupal repo (provided you have the access level required to do so - the access bar is low for sandboxes, but a lot higher for full projects). Note: You should only commit the Drupal-specific part.  The rest has to be hosted somewhere else.  Tell your users how to find it, and how it shall be combined with the Drupal-specific bridge.

However, there are other terms, and it looks like the BMLT License, as it currently appears, is a blocker:

  "BMLT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version." (my emphasis)

Drupal.org doesn't accept this license for any code in its repo.  For code to be permitted in the repo, it must be licensed under: "version 2 of the [GPL] License, or (at your option) any later version".  There are no exceptions to this rule.

Provided you can get the license right, there is nothing in the Drupal.org Git Repo Policy that prohibits a bridge module that requires other software (i.e. not packaged on Drupal.org) to be hosted on Drupal.org.

  For that matter, since Git is so horrible with submodules, I wonder if the Drupal repository can even handle submodules.

When a bridge module is hosted on Drupal.org (and there are plenty of them there already), it has to be combined with other required bits and pieces manually (i.e. there must be human readable instructions in the README about where to find the other software and how to assemble the pieces).  While I can see the beauty of using Git to pull all the pieces together, that is not how it is done.  Provided you and your users can deal with a two phase install where a human is required to do the assembly, it is doable.

As noted by Alfred Armstrong in a comment, the convention is to have a directory below the libraries folder (usually sites/all/libraries) to hold files the user must download from elsewhere. Then use the Libraries API module to integrate the bridge with the other files.


How do I wrap the label text of a checkbox with a span tag? I have noticed that Drupal 7 generates check-boxes with a markup like this:

<input type="checkbox">
Label text ..

I want to wrap  Label text .. inside a span tag, how to do that via the Drupal 7 API?

The result should be:

<input type="checkbox">
Label text ..

You would either need to override theme_form_element in your theme, or, do a hook_form_alter, target specific checkbox form elements, and change their #theme_wrappers callback to your own theme implementation.

I personally would do the latter, since overriding theme_form_element will change the default rendering for any form element in your theme, and that may not be desirable in every scenario.


$base_url and the mystery of broken feed images I recently upgrade my Drupal6 site to Drupal7 and migrated to getpantheon platform, I am hand-coding absolute image url's in nodes like this :

Despite using full absolute url's, images in feedburner are getting broken : http://feeds.feedburner.com/TheBestInternetNews as it's source http://www.megaleecher.net/rss.xml is outputting relative images.

Strangly, using $base_url = 'http://megaleecher.net'; (without www) in settings.php fixes the issue but using $base_url = 'http://www.megaleecher.net'; (with www) makes them relative again.

I have hired two drupal dev's from oDesk (https://www.odesk.com/o/jobs/job/Fixing-relative-image-paths-Drupal-rss-feed_~~0c48e61824bc3263/) and also asked for support from getpantheon but no solution.

Module Pathologic might help your problem, if you haven't tried that. Here is a quote about it (from the module's project page):

... is an input filter which can correct paths in links and images in your Drupal content in situations which would otherwise cause them to “break;” for example, if the URL of the site changes, or the content was moved to a different server. Pathologic can also solve the problem of missing images and broken links in your site’s RSS feeds.
Pathologic is designed to be a simple, set-it-and-forget-it utility. You don't need to enter any special “tags,” path prefixes, or other non-content noise into your content to trigger Pathologic to work; it finds paths it can manage in your content automatically.


How to avoid calling performRequiredValidation() for custom element I'm trying to integrate Selectize plugin  within Drupal 8 Form API.
The important thing that I want to create 'optgroup' options.

I've used Selectize module and created a custom FieldWidget Field plugin.
Almost everything works, but I got some troubles with validation of my element.
Every time my form element submitted I receive an validation error:

  "An illegal choice has been detected. Please contact the site
  administrator."

I've found the function, which sends me that error - performRequiredValidation().
I've found lines, so I can hack the core and add a case for my widget. But it's not a case for me.

if ($elements['#type'] == 'select') {
  $options = OptGroup::flattenOptions($elements['#options']);
}
else {
  $options = $elements['#options'];
}

So the only way I see - I have to avoid this validation somehow.
Plase help. Any suggestions would be appreciated.

Here is a simplified code of my widget:

namespace Drupal\my_fields\Plugin\Field\FieldWidget;

use Drupal;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsSelectWidget;

/**
 * Plugin implementation of the 'my_selectize_widget' widget.
 *
 * @FieldWidget(
 *   id = "my_selectize_widget",
 *   label = @Translation("My Selectize Widget"),
 *   module = "my_fields",
 *   field_types = {
 *     "entity_reference"
 *   },
 *   multiple_values = TRUE
 * )
 */
class MySelectizeWidget extends OptionsSelectWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    // Get our types.
    $grouped_types = _getTypesGrouped();

    // Override select form element.
    $element['#settings'] = [
      'plugins' => ['optgroup_columns'],
    ];
    $element['#type'] = 'selectize';
    $element['#options'] = $grouped_types;

    return $element;
  }

  /**
   * Get types grouped (options).
   */
  protected function _getTypesGrouped() {
    /**
     * // For example:
     * return [
     *   '1' => $this->t('One'),
     *   '2' => [
     *     '2.1' => $this->t('Two point one'),
     *     '2.2' => $this->t('Two point two'),
     *   ],
     *   '3' => $this->t('Three'),
     * ];
     */
  }

}

That error is caused from the following code.

  if (isset($elements['#options']) && isset($elements['#value'])) {
    if ($elements['#type'] == 'select') {
      $options = OptGroup::flattenOptions($elements['#options']);
    }
    else {
      $options = $elements['#options'];
    }
    if (is_array($elements['#value'])) {
      $value = in_array($elements['#type'], array('checkboxes', 'tableselect')) ? array_keys($elements['#value']) : $elements['#value'];
      foreach ($value as $v) {
        if (!isset($options[$v])) {
          $form_state->setError($elements, $this->t('An illegal choice has been detected. Please contact the site administrator.'));
          $this->logger->error('Illegal choice %choice in %name element.', array('%choice' => $v, '%name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']));
        }
      }
    }
    // Non-multiple select fields always have a value in HTML. If the user
    // does not change the form, it will be the value of the first option.
    // Because of this, form validation for the field will almost always
    // pass, even if the user did not select anything. To work around this
    // browser behavior, required select fields without a #default_value
    // get an additional, first empty option. In case the submitted value
    // is identical to the empty option's value, we reset the element's
    // value to NULL to trigger the regular #required handling below.
    // @see \Drupal\Core\Render\Element\Select::processSelect()
    elseif ($elements['#type'] == 'select' && !$elements['#multiple'] && $elements['#required'] && !isset($elements['#default_value']) && $elements['#value'] === $elements['#empty_value']) {
      $elements['#value'] = NULL;
      $form_state->setValueForElement($elements, NULL);
    }
    elseif (!isset($options[$elements['#value']])) {
      $form_state->setError($elements, $this->t('An illegal choice has been detected. Please contact the site administrator.'));
      $this->logger->error('Illegal choice %choice in %name element.', array('%choice' => $elements['#value'], '%name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']));
    }
  }

It means that the value set for $elements['#value'] (which could also be a value submitted from the users) is not contained in $elements['#options']. In fact, your code contains the following code.

$grouped_types = _getTypesGrouped();

// Override select form element.
$element['#settings'] = [
  'plugins' => ['optgroup_columns'],
];
$element['#type'] = 'selectize';
$element['#options'] = $grouped_types;

Since there isn't a _getTypesGrouped() function, you are essentially setting $element['#options'] to NULL, which means you are removing all the possible values the form field for that widget can have.
The correct code you want to use is the following one.

$grouped_types = $this->_getTypesGrouped();

// Override select form element.
$element['#settings'] = [
  'plugins' => ['optgroup_columns'],
];
$element['#type'] = 'selectize';
$element['#options'] = $grouped_types;

As for avoiding Drupal runs FormValidator::performRequiredValidation(), that is a bad idea. The purpose of that method is avoiding users submit a forget form; removing it means to mine the site security.

As side note, protected method don't need an underscore at the beginning of their name, as per Drupal coding standards.


How to present a field or another in a content type, depending on context I have a custom content type, let's call it seo_data. I want that the user will be presented, in the Admin view, with some of the fields, not all, depending on the context. So for some nodes, based on nid and other database queries, the user will see, for example, fields field_image and field_image_alt or field_video and field_video_alt. So, sometimes the user will see the fields corresponding to video or image, depending on some values in other data.

The question is about how can I, programmaticaly (prefered) or with a custom module, present just a bunch of fields.

For the module approach i recommend to evaluate this one: Conditional Fields.

  Conditional Fields allows you to manage sets of dependencies between fields. When a field is “dependent”, it will only be available for editing and displayed if the state of the “dependee” field matches the right condition.
  When editing a node (or any other entity type that supports fields, like users and categories), the dependent fields are dynamically modified with the States API.


Drupal SMTP is not working I am using STMP module for D7.

When i put test email abc@gmail.com, i have received the email but

When i check show original i am getting received from

Received: from usernem by myhost username with local (Exim 4.85)

Why it is so ?

Also i have enter wrong password and tried to send an email. i recieved the email

Seems SMTP is not working on my site

Below are my settings

Change and check

SMTP server: smtp.gmail.com
SMTP port: 587
Use Encrypted Protocol : Use TLS

Username: Your Email Id
Password: Your Password

For default email settings check

  /admin/config/system/mailsystem


Can I write two cron( hook_cron() ) in one module I have a custom module abc_xyz and i want to write two seperate cron for this module.

below is the code which i am trying but it is creating only one cron ,
with name abc_xyz_cron. it is not creating for zzz_yyy_cron

file name : abc_xyz.module

abc_xyz_cron(){

}

zzz_yyy_cron(){

}

No. You can implement hooks once per module due to the namespacing of the hook (mymodule_cron). However you can put conditions within the cron hook to do different things.

You might be looking for this instead: https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_cron_queue_info/7.x


change region block in module I want when a node saved,one block region be change.

for example: when a node be save,"user-login block" move to the content region.

please help me for resolve this problem.

thank you

try the context module and use node as the context and blocks as the reaction. you should be able to figure out the rest :)


Access a template variable from another template (or theme hook) I have two templates (and two corresponding preprocess hooks), one rendering a Paragraph, one rendering items from this paragraph.

How to access a variable available in the parent paragraph template (or preprocess Hook) from the items rendering template (or item preprocess hook) ?

paragraph--paragraph-row.html.twig

{{ content.MyVARIABLE }}  //it works

field--paragraph--paragraph-row2.html.twig

  {% for item in items %}

         {{ item }}

{% endfor %}

THANKS !

David

You can't access easily variables from other templates. But you can use the entity objects to access field values.

For a nested paragraph you find the parent paragraph in element['#object']:

field--paragraph.html.twig

{{ element['#object'].field_my_field.value }}


Get list of webforms that can be created by the current user Testing Webform in Drupal 8, I've found something strange when trying to get the list of the available webforms that a user can create.

My test environment: I've created a role, a user that belongs to that role and 3 webforms. In the "Access" tab of each of the webforms I've unchecked "Anonymous user" and "Authenticated User" and allowed access only to "Administrator" in 2 of the webforms. In the last one, I gave "create" access to my specific role.

Then, for testing purposes I created a rest service with the following code:

public function get()
{
    // Load all the available entities
    $entities = \Drupal::entityTypeManager()->getStorage('webform')->loadMultiple(NULL);

    // Check the access of the current user to each of the entities
    $forms = array();
    foreach( $entities as $entity_id => $entity )
    {
       $forms[] = array( "$entity_id" => $entity->access('create', NULL) );
    }

    return new ModifiedResourceResponse($forms);
}

I expected to get:

[{"webform1":false},{"webform2":false},{"webform3":true}]

But I get:

[{"webform1":false},{"webform2":false},{"webform3":false}]

In fact, I returned the $entity object as JSON and I found that the entity references the following permissions: "create", "view_any", "update_any", "delete_any", "purge_any", "view_own", "update_own", "delete_own". If I expand the tree, then I can see that inside the "create" permission of my webform3 entity, the permissions are properly referenced (Object->access->create->Roles->My Role is present only in the last form).

But the ->access('create') function is always returning false. The same goes for "view_any" and the other permissions. The only permission that returns true for all the forms is "view".

Is there any way that I can do this? :

    $entities = \Drupal::entityTypeManager()->getStorage('webform')->loadMultiple(NULL);
    $forms = array();
    foreach( $entities as $entity_id => $entity )
    {
       if( $entity->access('create', NULL) )
       {
           $forms[] = $entityid;
       }
    }
    return new ModifiedResourceResponse($forms);

Thanks and best regards.

I'll autoanswer my question :)

By grep-ing inside Webform source code I found that the permission name is not "create", but "submission_create", even if dpm($entity) is referencing "create".

$ grep -r "access" * | grep submission_create
webform_node.routing.yml:    entity_access: 'webform.submission_create'
Webform.php:                 if (!$webform || !$webform->access('submission_create')) {
(...)

So, this works as expected:

$entities = \Drupal::entityTypeManager()->getStorage('webform')->loadMultiple(NULL);
$forms = array();
foreach( $entities as $entity_id => $entity )
{
    if( $entity->access('submission_create', NULL) ) {
        $forms[] = $entity_id;
    }
}

It returns only the webforms that you are entitled to send submissions to.


How do I show only those node that have images available via a view? I have a content type with image, title, and body fields. I created a view to show these things on front end.
Here images are not available for all nodes of this content type.

I need to show only those nodes in front end that have images.

You can achieve it by following steps.

Add  Image field filter criteria.
Now in configuration, select operator Is not empty (NOT NULL).


How to get parent node values on inline entity form hook alter? I am using inline entity forms to create a paragraph in a node form. When I add a node I want the title of the node form to be copied to the paragraph when I click on "Add paragraph". I use hook_inline_entity_form_entity_form_alter to prefill the title field. That works, only I can't get the values from the node form. Not with the below code.

function example_forms_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {
  $node = $form_state->getFormObject()->getEntity();
  if ($node->getType() == "task" && $entity_form['#bundle'] == "improvement") {
    \Drupal::logger('Form state values')->debug("
" . print_r($form_state->getValues(), TRUE) . "
");
    \Drupal::logger('Node values')->debug("
" . print_r($node, TRUE) . "
");
    $entity_form['title']['widget'][0]['value']['#default_value'] = 'This is Jessica';
  }
}

Can someone help me solve this?

Perhaps you should try altering the paragraph form instead. When the paragraph is created, you will have access to it's host entity. Then just get the label of the host entity and assign it to the form element as a default value or value(can't remember which one).


hide empty exposed filters I have a view with an exposed filter that searches nodes for taxonomy terms. For example there are 10 terms but the nodes only use 7 of them. When the view is shown on a page the 10 terms show in the filter. 3 of the terms in the filter will yield zero results. I want to hide those terms (because they have zero results) and not make them available in the filter.

You can simply use Views Selective Filters Module for that.
Here is an introduction about this module :

This module allows to have an exposed filter only show options that belong to result set.
The options are calculated real-time with the current View's configuration, including the filters selected by the user so you get dynamic dependent filters, that is, when the value of one filter is changed, the list of options of the selective filters are updated accordingly to the trimmed down result set.


Display child items main navigation I created child elements for the main navigation. I went into the block configuration and adjusted it to show up to three levels of sub menu's.

For Drupal 7 I know that I used Nice Menu's to get the menu working with child links. But it's not usable yet with Drupal 8.

I was wondering if there was another module or how I could get my Child Links to show up.

You have to go to the menu configuration and manually check "expanded" for each item that has children. This is really annoying since there used to be a checkbox right on the list of links so you could do it on a single page at once. Not anymore.


Cannot update: "No available releases found" I cannot update some of the modules and the Drupal core itself from "Available Updates" menu. The error is "No available releases found". However, I can list the updates with drush ups.

Why?

Solution 1: SQL Query

While checking updates Drupal creates some rows inside the key_value table which should be deleted after checking is complete but looks like they doesn't for some reason. So deleting the related rows manually solved my problem:

DELETE FROM key_value WHERE collection = 'update_fetch_task';

Solution 2: hook_update_N()

If it is not possible to execute SQL queries via MySQL CLI on your server, then you might want to create a hook_update_N() in a custom module:

$database = \Drupal::database();
$database
  ->delete('key_value')
  ->condition('collection', 'update_fetch_task')
  ->execute();


Block file downloads for user Problem

I have a series of file fields on a user account where users can upload files. These files need to be attached to emails (by the system with drupal_mail) and removable by the user.

But they don't actually need to be downloadable. And it would be a nice extra level of security if they can't download the files, only upload, remove and upload again.

Has anyone ever tried this (admittedly fairly niche) idea before?

As it turns out this functionality was possible with only one extra module, the Content Access module.

Select the file field on the user account. You can find them at the following path:

/admin/config/people/accounts/fields

Edit the field and under permissions select, custom permissions. You'll need the Content Access module installed for this to work.

Then in permissions you can set custom permissions for the field. To allow a user to upload and not download, you give them only the ability to create or edit their field. You don't give them the permission to view it.


How to attach a library to a specific block I wonder how to attach a library to a specific block. I do this:

in mytheme.libraries.yml

   lib-name-script:
      js:
        header: true
        js/masonry.pkgd.min.js: {}
        js/main.js: {}
      dependencies:
        - core/jquery

in main.js

jQuery(document).ready(function() {

    $('.grid').masonry({
        itemSelector: '.grid-item',
        columnWidth: 220,
        horizontalOrder: true
    });
});

and in views-view--block-some.html.twig

{{ attach_library('theme_name/lib-name-script') }}

<div class="grid">
    {{ rows }}
</div>

But from some reason this dont works. :S

On the and of file I have:

<script src="/themes/theme_name/js/masonry.pkgd.min.js?oxcmsf"></script>
<script src="/themes/theme_name/js/main.js?oxcmsf"></script>

Was I corect load js, or mistake is on some other place?

It sure looks like you are on the right track to me. I've used the same approach myself. See: https://github.com/vegantriathlete/presentation/blob/master/templates/node--slide--full.html.twig

Have you cleared the cache? Maybe the theme registry needs to be updated to reflect the template you are using.

Have you viewed the page source of the page when that block is visible to see if the javascript is being included? Maybe the javascript is being attached and you've got a bug in your main.js. You aren't following the pattern of how to attach javascript. see: https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview


ASAF module redirects comment form to system/ajax#comment-cid after submission I use Asaf (ajax submit for any form) module to Ajaxify form submissions in my website. This module works well but in comment form submission, it submits the comment then redirects the page to system/ajax#comment-cid which is a blank white page.

How can I solve this or is there any way out to Ajaxify comment form submission?

You need to look in to issues of that module I found there one important information which help on this issue. https://www.drupal.org/node/2277137


Using PHP 5.2.17 in Acquia Dev Desktop 2 I'm using Acquia Dev Desktop 2 with Drupal 7. On PHP version selection menu, I only see "5.3.29", "5.4.33", "5.5.17".

Is it possible to switch PHP version to PHP 5.2.17 since most of my hosting provider based on PHP 5.2.17.

Or would you recommend anything other than Acquia Dev Desktop 2?

Thank you.

They dropped PHP 5.2 support with DevDesktop 2. It has hit EOL so you really shouldn't be developing against it.

That said, if you really want to do this, you can find old versions of DevDesktop that used PHP 5.2. I would guess you might hit problems if your end goal is to deploy to AcquiaCloud.


How to create custom ECK entity class (per bundle) With ECK I created Entity type Vehicle, and added 2 bundles, Car and Truck

Goal is to have a class Car so I can use Car::create() and similar entity functions, and also implement my own functions.

As far as I came is creating Vehicle class, and it's working, but I'm struggling with bundles.

I guess it is impossible to do what you want. A bundle is not a sub-class of an entity as you seem to be assuming.

Classes are always defined in code and are always provided by a module. ECK uses a workaround but in fact only defines one entity type: EckEntity, it then performs some tricks to let Drupal see this as different entity types.

Creating entities for every bundle dynamically (since a user can add / remove bundles) would be difficult and appears to be only possible using dirty tricks like this:

// With a property
$myclassname = "anewclassname";
$myproperty = "newproperty";
eval("class {$myclassname} { protected \${$myproperty}; }";

From: https://stackoverflow.com/a/15579465/1293725

I am pretty sure Drupal does not support this (luckily).

Bundles are stored as properties on the entity, often (always?) as the type property, have a look at this example:

// Create node object with attached file.
$node = Node::create([
  'type'        => 'article', // < - this is the bundle
  'title'       => 'Druplicon test',
  'field_image' => [
    'target_id' => $file->id(),
    'alt' => 'Hello world',
    'title' => 'Goodbye world'
  ],
]);
$node->save();

From: https://drupal.stackexchange.com/a/189095/9921

So in your case, you would need to do this:

$car = Vehicle::create([
  'type'        => 'car',
   ...
]);

Or define a new class for your bundles, but you would need to either use the eval method above to create a class for all your bundles, or define them in code and loose flexibility. Then in that class extend the Vehicle class and in the constructor provide the type or something. For the sake of readability of your code I guess it would be best to just follow conventions and not create classes for bundles.


How do I store node form data between form steps using ajax? I want to turn a node form into a multi-step form using ajax. I've added ajax-enabled submit buttons and some logic in a hook_form_alter (see below) to handle inc- and decrementing steps, and showing and hiding form items based on the current step. The stepping back and forth works great, in terms of rendering the correct elements.

The problem is, if I enter some data in one step, go forward or backward, and then return to the original step, the data I entered is gone from the form. If I check the value of the item for which I entered data using FormStateInterface::getValue(), the data is there when my alter hook runs when leaving the original step, but gone on subsequent next/back transitions. This problem also does not apply to data that is already in the form (e.g. when editing an existing node).

Clearly, I need to store the incoming values somewhere, but where? And then, how do I restore them to the form elements on the appropriate step?

My code (minimal example):

<?php
/**
 * Implements hook_form_FORM_ID_alter().
 */
function my_module_form_node_ajax_test_form_alter(&$form, $form_state) {
  // Define steps. Each child array is a step, and each string in the
  // a child array is a field that should be present on that step.
  $steps = [
    ['title'],
    ['body'],
  ];
  // Add wrapper.
  $form['#prefix'] = '
';
  $form['#suffix'] = '
';
  // If the step is not set, this is step 0.
  if (!$form_state->has('step')) {
    $form_state->set('step', 0);
  }
  // Get the current step.
  $step = $form_state->get('step');
  // If we have a triggering element, increment or decrement step as
  // appropriate.
  if ($trigger = $form_state->getTriggeringElement()) {
    switch ($trigger['#name']) {
      case 'next':
        $form_state->set('step', ++$step);
        break;

      case 'back':
        $form_state->set('step', --$step);
        break;
    }
  }
  // Show elements in the current step, hide others. Always show the
  // `actions` element, and all `form_*` elements.
  foreach (Element::children($form) as $element) {
    $form[$element]['#access'] = (
      in_array($element, $steps[$step])
      || $element == 'actions'
      || strpos($element, 'form') === 0
    );
  }
  // Show the back button if this is not the first step.
  $form['actions']['back'] = $step > 0 ? ajax_button('back') : NULL;
  // Show the next button if this is not the last step.
  $is_last_step = $step == count($steps) - 1;
  $form['actions']['next'] = !$is_last_step ? ajax_button('next') : NULL;
  // Show the submit button if this is the last step.
  $form['actions']['submit']['#access'] = $is_last_step;
}

/**
 * Return a render array for an ajax step button.
 */
function ajax_button($name) {
  return [
    '#type' => 'button',
    '#value' => $name,
    '#name' => $name,
    '#ajax' => [
      'wrapper' => 'ajax-form-wrapper',
    ],
  ];
}

This code is quite impressive. I did not think it was possible to build a multi-step entity form with a few lines in a form alter hook. To keep it this simple you can try to use the entity object to store the values, because the form object is serialized and cached between the steps and a method to build such an entity from the submitted values is part of the entity form class:

  if ($trigger = $form_state->getTriggeringElement()) {
    $form_object = $form_state->getFormObject();
    $new_entity = $form_object->buildEntity($form, $form_state);
    $form_object->setEntity($new_entity);


#ajax elements added in hook_form_alter miss after first ajax call I am modifying elements from the multiselect module to add ajax functionality. I wanted to use hook_field_widget_WIDGET_TYPE_form_alter() but I'm stuck in 7.14 and it requires 7.8.

So, I'm traversing the $form in hook_form_alter() to find the modify the 'multiselect' elements:

/*
 * Implements hook_form_alter()
 */
function ajax_multiselect_form_alter(&$form, &$form_state, $form_id) {
  _ajax_multiselect_search_children($form, $form);
}

/*
 * Look for multiselect elements
 */
function _ajax_multiselect_search_children(&$form, &$element) {

  if (isset($element['#type']) && $element['#type'] == 'multiselect') {
    _ajax_multiselect_modify_multiselect($form, $element);
  }

  $children = element_children($element);

  if (is_array($children)) {
    foreach ($children as $child) {
      _ajax_multiselect_search_children($form, $element[$child]);
    }
  }
}

When I find a 'multiselect' element, I add a new 'select' element to the form with the #ajax property copied from the original 'multiselect'.

/*
 * Modify the multiselect for ajax processing
 */
function _ajax_multiselect_modify_multiselect(&$form, &$element) {

  $element['#attached']['js'] = array(
    array(
      'data' => drupal_get_path('module', 'ajax_multiselect') . '/js/ajax_multiselect.js',
    ),
  );

  if (isset($element['#ajax'])) {

    $ajax_element_id = drupal_html_id('ajax_multiselect_element');

    // tell jquery where to find the id of the dummy select
    $element['#attributes']['class'][] = 'multiselect-element-id-holder';
    // transmit the id of the dummy select to jquery
    $element['#attributes']['data-ajax-multiselect-element-id'] = $ajax_element_id;

    $form[$ajax_element_id] = array(

      '#id' => $ajax_element_id,
      '#type' => 'select',
      '#ajax' => $element['#ajax'],
      '#options' => array(0,1),

//      '#prefix' => '
',
//      '#suffix' => '
',
    );

  }

}

Then, in Javascript, I trigger a 'change' event on the new (dummy) 'select' whenever the items in the 'multiselect' are altered.

  // create a new function that incorporates the old function to add/remove options in multiselect
  $.fn.oldAddOption = $.fn.addOption;
  $.fn.addOption = function(arguments) {
    this.oldAddOption(arguments);

    // find the tag that holds the id of the ajax multiselect element
    var tag_with_id = $(this).parent().parent().find('.multiselect-element-id-holder');
    // find the id of the ajax multiselect element
    var ajax_element_id = tag_with_id.data('ajax-multiselect-element-id');

    $('#'+ajax_element_id).trigger('change');
  }

This works for the first #ajax round trip, but after the first #ajax call anywhere on the page, my new (dummy) 'select' elements don't fire the correct #ajax.  In my Drupal Recent Logs, I get

Undefined index: #ajax in ajax_form_callback()

when I use the dummy select elements.

In network activity, I can see that the first #ajax response includes the correct array of commands for the replace action. But, after the first #ajax anywhere on the form, my new 'select' elements only receive a default #ajax settings response with no replace commands.

I think there is something about the way I am building in hook_form_alter that is not adding the #ajax property correctly after the first ajax call, but I can't figure out what it is.

The problem was relying on the IDs created by drupal_html_id() to match after ajax rebuild of the form. I fixed it by having jQuery find the dummy select elements by 'name' attribute.

  $.fn.oldAddOption = $.fn.addOption;
  $.fn.addOption = function(arguments) {
    this.oldAddOption(arguments);

    // find the tag that holds the id of the ajax multiselect element
    var tag_with_name = $(this).parent().parent().find('.multiselect-element-name-holder');
    // find the id of the ajax multiselect element
    var ajax_element_name = tag_with_name.data('ajax-multiselect-element-name');

    $('select[name="'+ajax_element_name+'"]').trigger('change');
  }

This code now sets unique element names instead of trying to set unique ids:

$ajax_element_name = drupal_html_id('ajax-multiselect-element');

// tell jquery where to find the id of the dummy select
$element['#attributes']['class'][] = 'multiselect-element-name-holder';
// transmit the id of the dummy select to jquery
$element['#attributes']['data-ajax-multiselect-element-name'] = $ajax_element_name;

$form[$ajax_element_name] = array(
  '#type' => 'select',
  '#ajax' => $element['#ajax'],
  '#options' => array(0,1),
);


in hook_preprocess_node, how to tell if node is being edited? In hook_preprocess_node (or other themable hook), what is the easiest way to tell if node is being edited? I would like to add some javascript only when viewing the node, not editing.

hook_preprocess_node() doesn't get fired for node edit pages so you don't need to do any checks, you can just add your JS as normal.


Run Drupal in localhost then migrate to online once it's finalized Possible Duplicate:
  How to migrate from test environment to production environment?

I'm sure a lot of template designers work in localhost before going online. My question is what's the best way to take your installation online once you're done playing around with it? Do you redo everything or do you just copy your localhost db then import it online?

I'm using XAMPP in case it matters. :-)

Since this is mostly likely a one time move (because the online version with likely be your master now) I wouldn't worry too much about perfecting the process. Just...

Dump the mySQL DB and place within the root.
Zip/Tar the codebase, including the files directory.
Move it to the server (via SCP or FTP), unzip/untar the whole thing.
Import the DB via: mysql -hHOST -uUSER -pPASS DBNAME < db.mysql
Bam!

For continual workflow I usually use:

Backup & Migrate to create database backups.
Git to move the code around (.gitignore your files directory)


Site url token in view Are there any way to get site's base URL value in a token within view to use in its header and field(s).

My local developments is on drupal installation in a sub-directory while on server it is on a domain.

You can use global $base_url; if you are using the PHP filter.


Secure pages and installing new modules (AJAX error) I've just configured my website to work with secure pages and everything seems to be working fine except for the ability to install a new module. Whenever I try, I get this error:

  An AJAX HTTP request terminated abnormally. Debugging information
  follows. Path:
  https://www.mysite.com/authorize.php?batch=1&id=329&op=do[1]
  StatusText: ResponseText: ReadyState: 4

It also offers an error page that says this:

  Notice: Undefined index: log in
  update_authorize_install_batch_finished() (line 250 of
  /home1/me/public_html/mysite.com/modules/update/update.authorize.inc).
  Warning: Invalid argument supplied for foreach() in
  update_authorize_install_batch_finished() (line 250 of
  /home1/me/public_html/mysite.com/modules/update/update.authorize.inc).
  Notice: Undefined index: log in
  update_authorize_install_batch_finished() (line 291 of
  /home1/me/public_html/mysite.com/modules/update/update.authorize.inc).
  Notice: Undefined index: tasks in
  update_authorize_install_batch_finished() (line 292 of
  /home1/me/public_html/mysite.com/modules/update/update.authorize.inc).
  Installation failed! See the log below for more information.

All I can find on secure pages and AJAX is to add */ajax/* to the "ignore pages" field. I've done that but I'm still having the same issue.
Has anyone else figured this out? I feel like it should be pretty standard stuff!

I got this same error, but the cause was unrelated to secure pages, so it may not apply to your case.  Mine resulted from upgrading to Drupal 7.3 and having uncommented the two lines in the .htaccess file "To redirect all users to access the site WITHOUT the 'www.' prefix." When I commented those two lines, my module installer started working again.  So if you have those two lines in .htaccess uncommented, try commenting them out and see if that makes a difference.


Syncing content between stage and prod Drupal 8, two versions of a site - dev and production.

How to move changes, especially changes in content from dev to production without destroying DB on production?

I know we have Features for configuration, but what about content?

Ideally, I would like to be able to add nodes, pages and edit existing ones, and then carry changes to the prod site, without destroying changes users created on the dev site - comments, new registrations and such.

What's the solution here? Export content to code?

Can someone give step-by-step on dev cycle?

Today I've discovered this site: http://www.drupaldeploy.org:

  A next generation comprehensive yet easy to use content staging
  solution built for Drupal developers and end users

There are several modules that work together, the "base" module should be Deploy:

  The Deploy module is designed to allow users to easily stage and
  preview content for a Drupal site. Deploy automatically manages
  dependencies between entities (like node references). It is designed
  to have a rich API which can be easily extended to be used in a
  variety of content staging situations.

On drupaldeploy.org you can find related modules.


Running two Drupal sites off the same database: Is it possible? Is it possible point a second Drupal site to an existing Drupal database, if that second site is only used to browse the content, no logins, registrations or content add/edit/deletes?

Is it possible? Yes. Should you do it? Probably not.

Using table prefixes, you can run two completely separate sites with table names like "site1_node" and "site2_node", so they don't collide. In your case, it sounds like maybe you also want to share data between the sites?

On solution to that, is to share tables between these two, but I strongly recommend against that. I've tried it on two different sites, and I've mostly gotten bit badly by it. Use Domain instead, to run two domains from a single Drupal install.


Where to store data for module I recently developed my first module. Part of its functionality is to store names, e-mails, and phone numbers of people on a newsletter. They sign up through the front-end and the admin can review and modify them on the backend.

In addition it also stores SMS messages and their details (date sent, number sent from, message, etc) that come in from a short code. This process is triggered by an HTTP request. Again, the admin can review and modify these in the admin of the website.

And finally, the same install will host 15-20 tables with ~20 columns and ~170 rows of health, education, and water quality statistics that can be queried from the website.

So that's everything: newsletter list, sms messages, data

I've never worked with a CMS and added so much to the default database. I also lack a lot of knowledge about databases. So my question is Should I store all this extra information in a different database? My current hosting allows for 20, and I'm only utilizing one.

Let me know if you need any extra information. Thanks in advance!

I'm afraid you need a long answer for this..
But using a data*base* to store different values like this is not the best way I guess.

You can use multiple databases with Drupal and switch them without a problem. But real question would be, why.

However, you can store categories in different table,and refer the category ID from the main sms message table. It's much easier to JOIN queries and get the data you want,rather than having a table for each category.
Also, I'd suggest using core functionality  when you can. With new entity system in Drupal 7,you can make a new entity, an SMS, and attach fields like category it to.

If you are storing settings of the module, consider using system_settings_form to store settings. You can set/get them using variable_set and variable_get. But make sure that you don't store big text using this.

Good luck!


How to validate all elements in Custom Widget I can validate a single textfield usig the fllowing code.

/**
 * @file
 * Contains \Drupal\field_example\Plugin\Field\FieldWidget\TextWidget.
 */

namespace Drupal\field_example\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'field_example_text' widget.
 *
 * @FieldWidget(
 *   id = "field_example_text",
 *   module = "field_example",
 *   label = @Translation("RGB value as #ffffff"),
 *   field_types = {
 *     "field_example_rgb"
 *   }
 * )
 */
class TextWidget extends WidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $value = isset($items[$delta]->value) ? $items[$delta]->value : '';
    $element += array(
      '#type' => 'textfield',
      '#default_value' => $value,
      '#size' => 7,
      '#maxlength' => 7,
      '#element_validate' => array(
        array($this, 'validate'),
      ),
    );
    return array('value' => $element);
  }

  /**
   * Validate the color text field.
   */
  public function validate($element, FormStateInterface $form_state) {
    $value = $element['#value'];
    if (strlen($value) == 0) {
      $form_state->setValueForElement($element, '');
      return;
    }
    if (!preg_match('/^#([a-f0-9]{6})$/iD', strtolower($value))) {
      $form_state->setError($element, t("Color must be a 6-digit hexadecimal value, suitable for CSS."));
    }
  }

}

But I have more elements in the widgets as follows

public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

     $element['cert_fqdn'] = [
      '#type' => 'textfield',
      '#title' => t('Fully qualified Domain Name'),
      '#value' => $items[$delta]->value ?: NULL,
      '#empty_value' => '',
      '#placeholder' => t('Fully qualified Domain Name'),

    ];
    $element['privatekey'] = [
      '#type' => 'textfield',
      '#title' => t('Private Key'),
      '#default_value' => isset($items[$delta]->cert_key) ?
          $items[$delta]->cert_key : null,
      '#empty_value' => '',
      '#placeholder' => t('PrivateKey'),
    ];

    // City

    $element['csr'] = [
      '#type' => 'textfield',
      '#title' => t('Certificate Signing Request'),
      '#default_value' => isset($items[$delta]->cert_csr) ?
          $items[$delta]->cert_csr : null,
      '#empty_value' => '',
      '#placeholder' => t('Certificate Signing Request'),
    ];
    $element['cert_crt'] = [
      '#type' => 'textfield',
      '#title' => t('Server Certificate'),
      '#placeholder' => t('Server Certificate'),
    ];

$element['create_cert_btn'] = array(
    //'#name' => implode('_', $element['#parents']) .'_create_cert_btn',
    '#type' => 'submit',
    '#value' => t('Create/Renew Cert'),
        '#element_validate' => array(
        array($this, 'validate'),
            ),

    );

    return $element;

  }

I need to get the values of all the elements  in validate function. How can I change the code to meet this . Please help.

A GOOD example of this approach is Field_example module from Example module for developers.(link here https://www.drupal.org/project/examples/releases/8.x-1.x-dev).

The widget with the "field_example_3text" id has also 3 elements: "r", "g, "b", and the values are accessed in validation function:

  foreach (['r', 'g', 'b'] as $colorfield) {

      $values[$colorfield] = $element[$colorfield]['#value'];
  }

So create an array containing your keys elements and loop into it, accessing the values by writing $element['your key']['#value'];

Have a look at this module.
The dpm of the $element variable looks like this:


Render an entity reference in a twig template I have a field that is an entity reference. I would like to print the entire entity in my controller.

I know I can print a particular field of the entity using something like

{{ teacher.field_classrooms.entity.field_classroom_one.value }}

but I need to print the whole entity rather than just one field.

How can I accomplish this?

first you should select show Rendered Entity in your content type field Manage Display section in admin/structure/types/manage/teacher/display (I supposed your content type is teacher based on your question), then in your node template  try to render the content field with something like

{{ content.field_classrooms }}


Adding labels to a Webform multistep form I have a form with 3 steps using the Webform module. Is there a way for me to identify what step I'm in so I can style it separately? What I'm after is to place text like Step 1 > Step 2 > Step 3 while highlighting the current step using CSS.

So far, I can't find any ID or class which tells me what step I'm in.

EDIT: Not that important but any suggestions on how I can place the text Step 1 > Step 2 > Step 3? I was thinking of adding the text in body but maybe there's another/better way? Just curious.

Just add a fieldset around each step with the labels "step 1-3"


Is it possible to search content by date in combined field filter views? Is it possible to search content by date in combined field filter views?

I have created a view in which content title ,content body and content date field is showing of node news type,i have added combined field filter for searching node in views but its searching by body and title but not by date .

What is the solution for this issue?

Yes.  Just make sure you have enabled the Date Views module (part of the Date project).


How to install PHP library using Drush My module depends on a PHP library (sites/all/libraries/xyz/xyz-library.php). It doesn't install unless the external library libraries/xyz/xyz-library.php is in place. Is there a way to install the library using Drush first and then install the module?

You can actually use drush make for this purpose. Drush make files can add in third-party dependencies which can be useful for just this kind of thing. Unless you intend to share this module with the community, in which case, you can issue a wget from the module itself similar to how other contrib modules do it. (See JW Player for an older example of that)

This is a good post on the topic by basically a Drupal genius. (Not me, I swear)

http://davehall.com.au/blog/dave/2011/05/17/drush-make-and-module-dependencies


Add a CSS class to field in content type I'm fairly new to Drupal and I want to add a custom CSS class to a custom field in content type.

I've created a content type called 'custom page' and I have a field called 'custom_page_main_title' the only thing I would like to do is to add a custom CSS class or iD to this

How can I do this please? Thanks!

I wrote a blog post about this a little while ago.  It mostly serves as a reference for understanding the method for targeting the markup for specific fields in specific content types utilizing theme functions in template.php which is stored in your theme's directory.

Definitely check it out.  If you can understand it, then in the future changing any of the HTML for particular fields, including the classes generated, becomes trivial.

To bring the pertinent content from my blog post into this thread, we have the following function in template.php:

function theme_field($variables) {
  $output = '';

  // Render the label, if it's not hidden.
  if (!$variables['label_hidden']) {
    $output .= '
' . $variables['label'] . ':&nbsp;
';
  }

  // Render the items.
  $output .= '
';
  foreach ($variables['items'] as $delta => $item) {
    $classes = 'field-item ' . ($delta % 2 ? 'odd' : 'even');
    $output .= '
' . drupal_render($item) . '
';
  }
  $output .= '
';

  // Render the top-level DIV.
  $output = '
' . $output . '
';

  return $output;
}

What you would do would be to replace the word theme in the function name to the name of your theme, and since you're targeting a specific field in a specific content type, you would append to the word field in the function name with __custom_page_main_title__custom_page.  So the function would look something like:

function themename_field__custom_page_main_title__custom_page($variables) {
  $output = '';

  // Render the label, if it's not hidden.
  if (!$variables['label_hidden']) {
    $output .= '
' . $variables['label'] . ':&nbsp;
';
  }

  // Render the items.
  $output .= '
';
  foreach ($variables['items'] as $delta => $item) {
    $classes = 'field-item ' . ($delta % 2 ? 'odd' : 'even');
    $output .= '
' . drupal_render($item) . '
';
  }
  $output .= '
';

  // Render the top-level DIV.
  $output = '
' . $output . '
';

  return $output;
}

Now you need to decide where in the structure of the field the class needs to be added, so perhaps add that on as an addition to your original question.


User permissions on admin area I created a new role, and this role should only have the permissions to insert/edit/remove to content types.

The problem is that the admin menu ( Navigation Menu ) doesn't show up in the admin area, and I can't seem to figure out why.

The other problem is that if I login with this user, and access the create node by putting admin/node/add ( since the Navigation menu doesn't show up ), I can create every content type available.

What am I doing wrong?

I think you should make use of proper permissions. If you are using Drupal7 , login in as admin and click on the people->permissions->content type-> add/edit/delete own contents. Once this option is enable and saved the user can modify only his content. I am not clear with your question, it would be glad if you make your question more precise.


How to apply an image style based on a condition? I've been following this discussion: How to apply an image style based on a condition (a date for ex.)? but unfortunately it has not been a success.

I would like to have the image to change based on a boolean field type being checked or not. When I check the On Sale checkbox, I would like the product image to be displayed with a different image-style.

My boolean field is named field_commerce_saleprice_on_sale.
1st image style is product_grid.
2nd image style on_sale.
In node--product.tpl.php I found the line

Thanks in advance for your help.

If you want to do it in template file, you can access your boolean variable using $node object. You can do following way :

if ($node->field_boolean[LANGUAGE_NONE][0]['value']) {
  print theme('image_style', array('path' => $node->field_image['und'][0]['uri'], 'style_name' => 'style1_name'));
}
else {
  print theme('image_style', array('path' => $node->field_image['und'][0]['uri'], 'style_name' => 'style2_name'));
}

Or :

If you are using panels, then you can use visibility rule to the fields by adding it twice with different image style.


Customise Webform Email Submission Data In the webform-mail.tpl.php template, it outputs the main form data using:

[submission:values]

I am using the html format (using mime-mail) and this outputs to the email html in the form:

NameName value

Is there a way I can customise the output so that it doesn't use the label field and uses a
 tag instead?

The problem with the  tag is that I cannot style it in Microsoft Outlook as it ignores all styling for this tag, and the email is quite difficult to read/understand.

I managed to find the answer from an identical question at How to use [submission:values] in Email template in Webforms.

Using the webform-submissions.tpl.php template I changed the output structure from:

NameName value

to:

Name

Name Value

Using the code below:

<?php
if ($format == 'html') {
    $output = drupal_render_children($renderable);
    $output = preg_replace('//', '
', $output);
    $output = str_replace(' ', ':

', $output);
    $output = str_replace('
', '

', $output);
    print $output;
}
?>

Now the styling in my Outlook emails look much better :)


How do I turn off the trimming of comments? In D8, I'm just wanting the comments that follow the content on a node page to appear in a normal fashion, but the comment list that appears displays a trimmed comment.

The markup itself contains trimmed text:

Please make results of this

and I note that the comment is contained in a h3 tag and the content tag is empty.

I've checked the comments type display settings for article, the content display settings for the comments, which is set to show a comment list (no other options), and see nothing set to trim.

Here is some additional information that might be useful:

Comment bodies ARE displayed IF the comment is a reply to another comment.
If the comment is NOT a reply to another comment, the meta shows (author, date, etc.) but no body, even though the comments do have body text in comment__comment_body.

The twig entry that is used in either case seems kosher to me:

  {#{% if title %}#}
    {#{{ title_prefix }}#}
    {#
{{ title }}
#}
    {#{{ title_suffix }}#}
  {#{% endif %}#}

    {{ content.comment_body }}

Have you looked if the format is not set to "trimmed" on the comment display page (/admin/structure/comment/manage/comment/display) ?


How to remove format description in date_popup form field? How can I remove format description in date_popup form field?

$form['payable_by'] = array(
    '#type' => 'date_popup',
    '#title' => $amount !== '' ? t('Instalment payable date for instalment @label', array('@label' => $amount)) : t('Instalment payable date for new instalment'),
    '#title_display' => 'invisible',
    '#default_value' => $payable_by,
    '#parents' => array('instalment', $key, 'payable_by'),
        '#date_format' => 'Y-m-d',
        '#date_year_range' => '-0:+1',
  );

Please check the image

Normally, you would just set the #description property of the form element, and it would be rendered. With the date_popup element implemented by the Date module it seems it is not possible: The form element is made of two sub-elements for which the value of the #description property is not taken into consideration.

As there are two branches, I will report what I have noticed in the development snapshot for both the branches.

Branch 7.x-2

The "date_popup" element is defined with the following code.

function date_popup_element_info() {
  $timepicker = date_popup_get_preferred_timepicker();
  $type['date_popup'] = array(
    '#input' => TRUE,
    '#tree' => TRUE,
    '#date_timezone' => date_default_timezone(),
    '#date_flexible' => 0,
    '#date_format' => variable_get('date_format_short', 'm/d/Y - H:i'),
    '#timepicker' => variable_get('date_popup_timepicker', $timepicker),
    '#date_increment' => 1,
    '#date_year_range' => '-3:+3',
    '#date_label_position' => 'above',
    '#process' => array('date_popup_element_process'),
    '#value_callback' => 'date_popup_element_value_callback',
    '#theme_wrappers' => array('date_popup'),
  );
  if (module_exists('ctools')) {
    $type['date_popup']['#pre_render'] = array('ctools_dependent_pre_render');
  }
  return $type;
}

The element has a process function that execute the following code.

  $element['#tree'] = TRUE;
  $element['#theme_wrappers'] = array('date_popup');

  if (!empty($element['#ajax'])) {
    $element['#ajax'] += array(
      'trigger_as' => array('name' =>$element['#name']),
      'event' => 'change',
    );
  }

  $element['date'] = date_popup_process_date_part($element);
  $element['time'] = date_popup_process_time_part($element);

Looking at the code for date_popup_process_date_part(), I notice the following code.

  $sub_element['#value'] = $sub_element['#default_value'];
  // TODO, figure out exactly when we want this description. In many places it is not desired.
  $sub_element['#description'] = ' '. t('E.g., @date', array('@date' => date_format_date(date_now(), 'custom', date_popup_date_format($element))));

As the code that date_popup_element_process() executes before to return the element is the following one, there is still an alternative.

  $context = array(
   'form' => $form,
  );
  drupal_alter('date_popup_process', $element, $form_state, $context);

Implementing hook_date_popup_process_alter() you could remove the description.

function mymodule_date_popup_process_alter(&$element, &$form_state, $context) {
  unset($element['date']['#description']);
  unset($element['time']['#description']);
}

Similar code is present in the branch 6.x-2.

Branch 7.x-1

There are few differences with the branch I previously described. (See the code repository.)

The first is the code that in date_popup_process_date_part() sets the description, which is the following one.

  $sub_element['#value'] = $sub_element['#default_value'];
  // TODO, figure out exactly when we want this description. In many places it is not desired.
  $sub_element['#description'] = ' '. t('Format: @date', array('@date' => date_format_date(date_now(), 'custom', date_popup_date_format($element))));
  return $sub_element;

The second difference is that date_popup_element_process() (the process function for that element) is not invoking hook_date_popup_process_alter().

function date_popup_element_process($element, $form_state, $form) {
  date_popup_add();
  module_load_include('inc', 'date_api', 'date_api_elements');

  $element['#tree'] = TRUE;
  $element['#theme_wrappers'] = array('date_popup');

  $element['date'] = date_popup_process_date($element);
  $element['time'] = date_popup_process_time($element);

  if (isset($element['#element_validate'])) {
    array_push($element['#element_validate'], 'date_popup_validate');
  }
  else {
    $element['#element_validate'] = array('date_popup_validate');
  }
  return $element;
}

The only alternative in this case would be to implement hook_element_info_alter() to add a process function to the element.

function mymodule_element_info_alter(&$type) {
  if (isset($type['date_popup'])) {
    $type['date_popup']['#process'][] = 'mymodule_date_popup_process';
  }
}

function mymodule_date_popup_process($element, $form_state, $complete_form) {
  unset($element['date']['#description']);
  unset($element['time']['#description']);

  return $element;
}

The code for branch 6.x-1 is similar to the code of branch 6.x-2.

In both the cases, the comment reported in the Date module code suggests they will alter the code not to use the description that is now shown. For this reason, I would suggest to implement the necessary code in a custom module, and remove that code once the Date module is changed.


Creating a filter of content types? I have a content type called college facilities. This displays ALL the college facilities that are added. I would like to create more content types called:

Services
Food
College Supplies
Other

I was wondering is it possible to create a drop down filter on the college facilities page so that if a user select all then all of them are displayed or Food then only food content types are displayed?

This is what I would like it to look like with ALL being pre selected.
Is this possible?
I apologize I am very new to drupal and Im using Drupal 7.

If I understand correctly, you need to create Views page where you add exposed filter on the content types.

This is how you create an exposed filter
https://www.youtube.com/watch?v=2Yk6rre3vi8

If that is unclear for you, I will make a screenshot.

Regards,

Oleg


How to check if an edited form is editing a translated node I have a content type named film.

Original language of a film is FR.

Let say I have 2 translatable fields on a total of 10 fields in film.

I am using this code to alter the add/edit form of film:

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case 'node_film_edit_form': // edit
    case 'node_film_form': // Add
      alter_film($form, $form_state, $form_id);
      break;
    ...
  }
}

In the alter_film function, I would like to add a custom submit only if the edited form is for French (Original language)

function alter_film(&$form, FormStateInterface $form_state, $form_id) {
  ...
  //HERE IS MY PROBLEM:
  //HOW TO KNOW IF IT IS TRANSLATED FILM
  if (! $is_translated_film){
    $form['actions']['submit']['#submit'][] = "submit_film";
  }
  ...
}

The question is: what check could be made to know which form is edited: the original language form (10 fields) or the translated language form (2 fields)

As a side question, I don't understand why there is no difference in the dpm($form); output if I execute one in the French form and the other one in the English form.
I am asking this, because in /admin/config/regional/content-language, I have checked Hide non translatable fields on translation forms.
And I would expect to have 10 fields in the french form array and only 2 (translatable) fields in the translated form array.

In the translated form, only 2 fields are displayed as expected, but I am wondering why the 10 fields are included in the array.... I ask that just out of curiosity

I could answer myself for the first question. The following line will give me the edited language.

$form_state->getFormObject()->getEntity()->get('langcode')->value;

But, maybe, the following is better:

$is_original_language = $form_state->getFormObject()->getEntity()->get('default_langcode')->value;

It is better, because original language could vary. In this case on the Add/Edit Node, Add new translation and Edit translations the return value can be parsed directly. Add Node or add new translation returns a Boolean while the edit forms return an int (1/0).


Customize the form-portion of a view There might be a really simple answer for this, but I haven't found it yet.

I'm using a view with a few exposed filters.  The form it generates is too basic, and I want to restructure it a bit, with some "+ advanced" expanding/collapsing divs and things like that.

What method do I hook for this?  Or is there a better way?

You can override views-exposed-form.tpl.php template.
In this overrided template you can putup own div wrapper etc.
How to override any template(tpl) visit here.

You can also use hook_form_alter. It perform alterations before a form is rendered. So using this add some alteration on form.


Displaying a menu's child links It seems that, by default, Omega, and other themes do not render child links.

I have tried various modules (e.g. Superfish, and Megamenu), but they do not offer a structure that allows me to theme to the design I am after.

I found this page, but it does not seem to use theme_links().

Is there a simple way to enable all my menu links, and still be able to hook into it before they are rendered?

Go to your parent menu item, edit it and click on the 'Show as expanded' checkbox. Now all the children menu items should be visible from the top level.


How to template a view and be able to manipulate the content with it? I'm wondering if there's a way to template a View, and actually be able to manipulate the content within it. I know I can theme the 'wrapper' around the View, but I'd like to be able to override what's inside the View, so I can create my own loops et cetera.

Right now I'm just having to create a view, and then make a template for the block (block--views-block--view-name.html.twig for example). This doesn't give me any access to the fields within the view though. I just have to wrap my markup around a {{ content }} tag, and adjust the formatting settings of that view.

I believe this functionality was available in D7, can I do it in D8?

EDIT:
Another example I just thought of is if I had a content type for locations of offices, I then made a view to display a list of these locations to show on a page. I want to be able to have access to data stores inside each location. This way I can then create loops etc on my contact page, looking through each location, displaying it how I'd like.

You should create new display modes for the content in question, and provide twig templates for them (e.g. node--type--display-mode; I am unsure of the pattern). Then you can change the View to show the rendered entity, and select that display mode, which will use the twig template for it.

This will be a lot easier IMO for what you are trying to do and make the View itself more maintainable long term. For example, maybe you wind up having to make multiple views... editing all those fields via Views is going to become a real pain real fast. Changing the field configuration in the display mode settings of the respective entity type will be reflected in the View immediately without changing the View itself (unless caching is enabled, then clear it).

See: http://www.mediacurrent.com/blog/drupal-8-theming-without-panels for some background.


How to implement POST request in custom services module? I want to send the POST parameters from my PHP client library, for that how to make my custom services module?

function module_rest_services_resources() {
  return array(
   'new_note' => array(
         'retrieve' => array(
           'help' => 'Retrieves a note',
           'file' => array('file' => 'inc', 'module' => 'module_rest'),
           'callback' => '_module_rest_retrieve',
           'access callback' => '_module_rest_access',
           'access arguments' => array('view'),
           'access arguments append' => TRUE,
           'args' => array(
             array(
               'name' => 'id',
               'type' => 'int',
               'description' => 'The id of the note to get',
               'source' => array('path' => '0'),
               'optional' => FALSE,
             ),
           ),
         ),
     ),
  );
}

Its working with GET request, what i have to change here to process the POST?

In order to change into the POST request. You just change the source of resource from path to data. For example:

function module_rest_services_resources() {
  return array(
  'new_note' => array(
     'actions' => array(
       'retrieve' => array(
         'help' => 'Retrieves a note',
         'file' => array('file' => 'inc', 'module' => 'module_rest'),
         'callback' => '_module_rest_retrieve',
         'access callback' => '_module_rest_access',
         'access arguments' => array('view'),
         'access arguments append' => TRUE,
         'args' => array(
           array(
             'name' => 'id',
             'type' => 'int',
             'description' => 'The id of the note to get',
             'source' => array('data' => 'id'),
             'optional' => FALSE,
            ),
          ),
        ),
      ),
    ),
  );
}