How to remove comma from taxonomy tags I want to style my taxonomy tags value. Actually In this Tags accepts comma separated value, so if I am rendering it on page it comes along with the comma.

I want separate values without comma.

How can I do that?

Hope you are using views to display the nodes. If so, then click on the tags field in the Fields and in the "MULTIPLE FIELD SETTINGS" give space in the separator.


Caption on CKEditor with Media embed only allows 128 characters Using Drupal 8, the Media module, and the CKEditor that comes with D8. When you add an image media item, you get your screen like this...

But that caption field only allows 128 characters. Media (I believe) seems to be setting a maxlength of 128 (maxlength="128"). You can still add more characters if you Embed, then edit the source it supplies, but it's still going to chop off what you've added if you double click on that image (it's technically a drupal-entity element) to bring the "Embed media" window up again.

Since this "Caption" field is not dealing with any kind of data/database storage constraints, 1.) can I change this and 2.) does this even make any sense for it to have a maxlength set?

If anyone has a clue how to change it, that'd be most helpful.

This should do the trick no need to install any module, substituting 500 with whatever you want the limit to be

 function mymodule_form_entity_embed_dialog_alter(&$form, $form_state, $form_id) {
      if(isset($form['attributes']['data-caption'])) {
        $form['attributes']['data-caption']['#maxlength'] = '500';
      }
    }


function uc_stock_adjust($sku, $newStock); not returning any value Iam using uc_stock module functions of ubercart module in my function but not getting result as i want. here is my code:

function my_module_node_presave($node) {
  if ($node->type == 'add_stock') {
    if (module_exists('uc_stock') && function_exists('uc_stock_adjust')) {
      $newStock = $node->field_stock_value['und'][0]['value'];
      drupal_set_message('new stock :' . $newStock);

      $sku = $node->field_sku['und'][0]['value'];
      drupal_set_message('sku :'. $sku);

      $key = $node->field_reference['und'][0]['nid'];
      drupal_set_message('key :'. $key);

      $items = field_get_items('node', $node, 'field_sku');
      drupal_set_message("
" . print_r($items, true) . "
");
      $sku = $items[0];
      drupal_set_message("
" . print_r($sku, true) . "
");

      $stock_adjust = uc_stock_adjust($sku, $newStock);
      drupal_set_message('stock_adjust :'.$stock_adjust);

      $stock_set = uc_stock_set($sku, $newStock);
      drupal_set_message('stock_set :'.$stock_set);
    }
  }
}

in my code

$stock_adjust = uc_stock_adjust($sku, $newStock);

$stock_set = uc_stock_set($sku, $newStock);

the above two functions were returning no value. now anyone can tell me whats the problem in my code

Function uc_stock_adjust has no return value.

  Description: This function adjust a particular product SKU by a
  certain value (a positive integer will add to stock, a negative
  integer will remove from stock).

  Parameters:
  $sku - The product SKU that will have its stock level adjusted
  $qty - The quantity to add to the stock level

  Return value: No return value.


Access Denied on Drupal 8 image styles despite correct permissions I have a functioning D8 site that has recently started displaying odd behaviour. Image styles are no longer generating correctly.

The sample.png used in the image styles config page generates fine (including if I delete the file manually from the image styles dir).

I have recursively set 0775 (dirs) and 0664 (files) to the entire sites/default/files directory, but the error persists. Error log just shows "access denied" - nothing more informative.

Drupal version is 8.1.9.

Any ideas? The site looks pretty lame right now!

I have had issues in the past where derivatives weren't generating correctly intermittently and it was due to disc space running out.  When logs were purged the image derivatives would generate, but otherwise, the server was running out of space.  So that's one idea.


Change Field Label from h2 to div I am looking for days the PHP file which characterizes the Field label with the  tag.
From a certain number of  tags that SEO is technically quite counterproductive.

Can Someone show me how or where to
 Taxonomy Term:
in
 Taxonomy Term:
can change?

I found this solution, among other things, but nothing works.
Change a label element to an <h2>?...

Im using Commerce Kickstart 2.39 on AT-Commerce

Thank you very much

If you want a fast solution, you might want to look into using Display Suite or Fences... I recommend Display Suite.

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

It will let you change the label as you want from the admin UI, no file editing needed.


Add product - price and sku field missing When I want to add a product, the field price and SKU are missing.

Running on Drupal 8.7.1 on MAMP on macOS and PHP 7.1.23

Any idea?

A variations tab, which is skus and prices. A product is paired to 1 or more variations.

Answer provided by smccabe from commerce slack.


Panelizer settings page not found for OG group node I have a site with several content types, all of which are OG content except one type, Group, which is a group.

I also have Panelizer and Panels Everywhere enabled. When I go to edit the default Panelizer settings for each content type, I have no problem doing so, except when the node type is Group. I can turn on Panelizer for Groups but then when I go to set the default settings for individual view modes, I get a "page not found" error.

I've cleared caches, rebuilt the registry, and even reinstalled Drupal, to no avail.

It turns out that this is correct, though not very user-friendly, behavior. The user must enable a default panel, or trying to set settings for the default panel will not work.

on admin/types/manage/[nodetype]:


unable to migrate site from one server to another I have to migrate as site from one server to another. I exported the databaseusing MySqladmin which I also used to import the db on the new server, I copied all files over but I keep getting errors like:
Fatal error: require_once(): Failed opening required '/home/quaaout/public_html/drupal-7.43/sites/all/modules/rules/modules/events.inc' (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/quaaout/public_html/drupal-7.43/sites/all/modules/rules/rules.module on line 9

so I tried loading the latest drupal 7 core 7.43 but I get exactly the same. I then tried to erase that one module rules but I got the error for the next, I deleted and the same error would popup for modules rules, apps, contentanalysis,kwresearch (which I deleted one after the other) but after the last one I stopped and thought there must be another way to get rid of this error, but how? Please advise!
Thanks!

EDIT1

And then since I updated my db version, I tried to call update.php but that won't work i.e. the server returns nothing, I get an empty page in firefox and Chrome says: The  page isn’t working

EDIT2

What I also tried is: wget --ftp-user=USER --ftp-password=PASS -r ftp://ftp.myolddomain.com/ . to download the complete site the new host but I still get Fatal error: require_once(): Failed opening required '/home/quaaout/public_html/ftp.quaaoutlodge.com/sites/all/modules/rules/modules/events.inc' (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/quaaout/public_html/ftp.quaaoutlodge.com/sites/all/modules/rules/rules.module on line 9 when trying to access the page through the new domain...

EDIT 3

Okay, seems like the initial wget command didn not catch all the files and I had to re-copy the sites/all/modules/ and sites/all/themes. Seems like I've caught everything now. I'm not sure why this would not have worked initially.
Manoj Bisht, please return and add your comment as answer to get the credit you deserve, after all, I only started checking for the files within the modules & themes directories after you told me to...

Have you tried backup migrate?

http://drupal.org/project/backup_migrate

Make sure you have a vanilla drupal install working perfectly, then copy the sites/all folder from your first server, enable backup migrate and then restore the backup from the first server.

Basically, it will be a lot easier to troubleshoot if you're on a vanilla install and backup migrate is perfect for this.


How to process the data which type is BLOB? I get the following data from MySQL by db_query(). The type of the column is BLOB.

  a:2:{s:10:"attributes";a:1:{s:5:"title";s:0:"";}s:8:"langcode";s:7:"zh-hans";}

How should I process it?

Pass it to unserialize(). That is the string obtained from serialize(), when the argument is the following array.

$array = array(
  'attributes' => array('title' => ''),
  'langcode' => 'zh-hans',
);

serialize() is the function used from Drupal when the data to save in the database is an array.


Update a field type with hook_update() My module provides config that creates a field:

field.storage.paragraph.field_accordion_section_title.yml

langcode: en
status: true
dependencies:
  module:
    - paragraphs
    - text
id: paragraph.field_accordion_section_title
field_name: field_accordion_section_title
entity_type: paragraph
type: text_long
settings: {  }
module: text
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false

I would like to update the field to use string_long instead of text_long.  I would like to handle this via hook_update() since the module was already installed on multiple sites.  I tried the following:

use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;

/**
 * Updates accordion section title to string type.
 */
function my_module_update_8001() {
  if ($fields = \Drupal::entityTypeManager()->getStorage('field_storage_config')->loadByProperties(array('field_name' => 'field_accordion_section_title'))) {
    foreach ($fields as $field) {
      $new_field = $field->toArray();
      $new_field['type'] = 'string_long';
      $new_field = FieldStorageConfig::create($new_field);
      $new_field->original = $field;
      $new_field->enforceIsNew(FALSE);
      $new_field->save();
    }
  }
}

I get the following error when updating: Failed: Cannot change the field type for an existing field storage.

As the error message says, this is not supported. There is no API that will do it for you.

There was a similar question recently but I can't find it right now, just this one: How do I change the type of a field attached to a content entity?

In short, you have two options:

Create a new field, write a script to move over all your data, then delete the old field.
Manually alter the database schema and low-level config data as well as the data that Drupal has stored about the field type and its schema. This is by far the more complicated option.


Better Exposed Filters: filter options display I have created some BEFs as checkbox list to allow multiple selectios, the filtering options are many, so I want only limited filter options to appear say 5. If I click on more then only it should show the remaining.

for eg:

FILTER OPTIONS
op1
op2
op3
.
.
.
opn

I want them to appear as

FILTER OPTIONS
op1
op2
op3
op4
op5
   more
on clicking more link it has to display the remaining options. How ca i achieve this?

You have to use javascript like show/hide jquery plugin/scripts show/hide jquery plugin/scripts  . just take the id of dropdown list and then apply jquery where you want. include jquery script where you mostly write. its upto you.


Caching $_SESSION data for anonymous users I recently inherited a Drupal 6 website that is using $_SESSION to store a lot of anonymous user data. Currently none of this $_SESSION data can be accessed while caching is enabled.

I have considered using cookies to work around this limitation but would like a fallback for users without javascript enabled.

Is there a way to do this in D6, D7 or the upcoming D8?

I think your best option is to use 2 cookies. Set one cookie that checks to see if the browser has JavaScript enabled. If JavaScript cookie is not there, the user gets an uncached page. If JavaScript does exist then drop a cookie containing the session data. Do the uncached page check in your settings.php file.

If you have something like Varnish or Nginx on your web stack, checkout ESI as it can work how you want it if the browser doesn't support JavaScript.

Also checkout http://drupal.org/project/authcache as it might be what you're looking for (minus the JS part...)


Some content is not displaying on one of my Drupal 7 pages I inherited a development theme and I am a Drupal newbie. I don't seem to be able to print out any new fields that I add to my content types. I put this code in node.tpl.php:

<?php echo render($content['field_my_text']);?>

I have the corresponding name in my content type. Any ideas on what could be going wrong?

Thanks!

I figured it out. The new field was initially set to hidden inside the manage display tab of the "full content" (instead of the default).


Replacing an object of the UserLoginForm class with one of my own class Is it possible to replace an object of the UserLoginForm class with one of my own class?

What I want to do is replacing the login form with a custom one which would ask users to enter a code sent to their email address, once they entered the correct user credentials.

The problem is that an object of that class is created from UserController::userPage().

if ($user->id()) {
  $response = new RedirectResponse(url('user/' . $user->id(), array('absolute' => TRUE)));
}
else {
  $response = drupal_get_form(UserLoginForm::create($this->container), $request);
}

I know I can implement hook_form_alter() to alter the form, but I would like to use a class like UserLogin, and replacing $form_state['build_info']['callback_object'] with the object of my class in hook_form_alter() is probably too late.

Is it possible to use a class for altering the user login form? How?

As I said in the question, the problem was that UserController::userPage() expressly created an object of the class UserLoginForm. The method has been changed, and now it contains the following code, which doesn't contain any explicit reference to that class.

public function userPage() {
  return $this->redirect('entity.user.canonical', array('user' => $this->currentUser()->id()));
}

Using a route subscriber that extends RouteSubscriberBase is possible to change the form associated with a route.

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

class MymoduleRouteSubscriber extends RouteSubscriberBase {
  public function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('user.login')) {
      $route->setDefault('_form', '\Drupal\mymodule\Form\MyModuleLoginForm');
    }
  }
}


Webform Error Occurs During Configuration Import Currently we are having some trouble handling webform module configuration on our various environments.

When running a configuration import drupal config:import --directory=$SYNC_DIR on our dev environments with a fresh database from production we receive the following error:

[ERROR] An error occurred while trying to write the config file: "Entities exist of type Webform submission and Webform Borough Newsletter. These entities need to be deleted before importing."

This particular web form (Borough Newsletter) has not been exported as config from production and has no associated yaml file, additionally it has some submissions in the database.  When we remove all submissions of this particular webform the import completes, but removes any webforms not stored as config (no surprise there).  We also tried to use the Config Ignore to prevent webforms from importing configuration, but we still got the above error.  I have three main questions:

Our webforms are created on production by non-developers.  Is the proper workflow to start exporting webform config from prod and bring it to our dev environments top down?
What exactly was the cause of the error we got during import (mentioned above)?
How come we still get an import error when we explicitly attempted to block any webform config from being imported? Was it due to a dependency on webforms from some other configuration item?

Webform Module Version: 8.x-5.3

Drupal Core Version: 8.6.17

Thank you in advance!

Ad 1)
I guess the proper workflow is never do any config changes on prod, completely disable all config UIs on prod and do only one-way forward-syncs from stage to prod. But I'm also working for small businesses, who do their work directly on the prod server, so I also can't use the "proper" workflow.

My personal workflow is

Prod always is the source of truth (no config ignore).
Before development, always pull config from prod.
drush @prod site:ssh drush_cex_and_git_push.sh "Backsync"
git_pull_and_drush_cim.sh
During development, don't change config on prod to avoid merging troubles.
After development, push to repository and pull changes on prod.
drush_cex_and_git_push.sh "New awesome feature"
drush @prod site:ssh git_pull_and_drush_cim.sh

This workflow is NOT safe for concurrent config changes, so this will not work well if you have frequent config changes on prod or long-term or multi-person development jobs!

Prerequisites:

SSH access on prod. Add dev machine's SSH key on prod's ~/.ssh/authorized_keys.
Create drush site environment entries for @dev and @prod in ~/drush/sites/self.site.yml to execute drush commands on prod environment while working on dev machine. (doc)
Use git with SSH keys for quick syncing config between environments without password prompts.
Use some bash scripts for single-command syncs between environments

git_pull_and_drush_cim.sh

#!/usr/bin/env sh
echo ""
echo "PULL and IMPORT all updates..."
echo ""

git pull
echo ""
echo "DELETING unused config files"
echo ""
git clean -fd config/sync
echo ""
./composer.phar install --no-dev
./vendor/bin/drush state:set system.maintenance_mode 1 -y
./vendor/bin/drush cache:rebuild
./vendor/bin/drush updatedb -y
./vendor/bin/drush config:import -y
./vendor/bin/drush core:cron -y
./vendor/bin/drush state:set system.maintenance_mode 0 -y
./vendor/bin/drush cache:rebuild

drush_cex_and_git_push.sh

#!/usr/bin/env sh

if [ -z "$1" ]; then
  echo "Usage: drush_cex_and_git_push.sh <commit message>"
  echo ""
  exit 1
fi

echo ""
echo "EXPORT and PUSH all updates..."
echo "Commit Message: $1"
echo ""

./vendor/bin/drush config:export -y
git add -A
git commit -m "$1"
git push

I'm also using those scripts as part of my semi-automated maintenaince script running composer updates for all my projects.

Ad 2)
drush config:import deletes all existing configs from the DB that are not present in the sync directory. Since you cannot delete an entity config while there are dependent entity instances in the database, you get this error message.
It would be the same as if deleting node.type.article.yml config while still having article nodes in the database.

There are a lot of blog posts on large enterprise projects with a strict dev --> stage --> prod workflow. I'd love to see more info on how to handle a small dev <--> prod workflow.


How to include js file in a module which depend on jquery? I have a module called catalog_menu

I included a js file within this module in this way:

drupal_add_js(drupal_get_path('module', 'catalog_menu') . '/js/catalog_menu.js');

Now in the browser I get this error message:

Uncaught TypeError: Property '$' of object [object DOMWindow] is not a function

I think that the problem is that catalogo_menu.js is loaded before jquery.js (the jquery library)

What is the right way to load a js file which depends on jquery library?

I actually think it is pretty unlikely that you have a weight problem, unless you redefined your module to have a extremely low weight.  Make sure you have JS optimization turned off, and then do a view source and make sure jQuery is the first script loaded (nearly always is).

My two guesses are

You have a JS error somewhere else, and this is a weird side effect.
You have a JS error in your catalog_menu.js (or another file) that is nuking the $ object by accident.

Also, you should you use an anonymous closure or JS module pattern for code, because Drupa 7 defaults jQuery no-conflict mode.

(function ($, Drupal) {
  function init () {
    $("body").addClass("catalog-menu");
  }

  Drupal.behaviors.catalog_menu = {
    attach: init
  };
}(jQuery, Drupal));


$form_id: What is the difference between #id and #value? I am trying to find the $form_id using the Devel module.

Sometimes when I output a form, $form_id is output with a single value.  However, sometimes the output of dpm($form) looks like this:

What is the difference between #value and #id here?  Which is the $form_id?

$form_id always has _ in it. Because in hook_form_FORM_ID_alter() you always have to put replace FORM_ID with $form_id so you can't put - in function name.

$form_id: String representing the name of the form itself. Typically this is the name of the function that generated the form.

And #id is html safe id. id attribute for form tag.


How to insert checkbox value in MySQL database $languages_knows=array(
'English' =>t('English'),
'Hindi' => t('Hindi'),
'Marathi' => t('Marathi')
 );

$form['languages_known'] = array(
'#title' => t('Language Spoken'),
'#options' => $languages_knows,
  '#type' => 'checkboxes'
);
function lawyer_register_form_submit($form, $form_state)
{
//Does something with successfully submited form fields.
global $user;
 $user = db_insert('lawyer_details')
->fields(array(
'first_name' => $form_state['values']['first_name'],
'middle_name' => $form_state['values']['middle_name'],
'last_name' => $form_state['values']['last_name'],
'languages_known'=>$form_state['values']['languages_known'],
))->execute();

Please help me.they gives error

  PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away: INSERT INTO {lawyer_details} (first_name, middle_name, last_name, street_address, city, country, phone, email_id, speciality, languages_known) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9);

'checkboxes' are array - serialize values on insert (and unserialize when get it), something as

'languages_known'=>serialize($form_state['values']['languages_known'])

edit:

full working code for example form

function mymodule_menu() {
  $items['test-form'] = array(
    'page callback' => 'drupal_get_form',
    'page arguments' => array('test_form'),
    'access callback' => TRUE,
  );

  return $items;
}

function test_form($form, &$form_state) {

  $languages_knows=array(
    'English' =>t('English'),
    'Hindi' => t('Hindi'),
    'Marathi' => t('Marathi')
  );

  $form['languages_known'] = array(
    '#title' => t('Language Spoken'),
    '#options' => $languages_knows,
    '#type' => 'checkboxes'
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  return $form;
}

function test_form_submit($form, &$form_state) {
  //Does something with successfully submited form fields.
  global $user;

  $user = db_insert('lawyer_details')
    ->fields(array(
      //'first_name' => $form_state['values']['first_name'],
      //'middle_name' => $form_state['values']['middle_name'],
      //'last_name' => $form_state['values']['last_name'],
      'languages_known'=>serialize($form_state['values']['languages_known']),
    ))->execute();
}

also you need to have install file, same as mymodule.install with table/field schema:

<?php

function mymodule_schema() {
  $schema['lawyer_details'] = array(
    'description' => 'Details comments here.',
    'fields' => array(
      'id' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Some identifier.',
      ),
      'languages_known' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'description' => 'Some description here.',
      ),
    ),
    'primary key' => array('id'),
  );

  return $schema;
}

then delete your table, uninstall module (uncheck, save, uninstall) and install again.

test

hint: see https://www.drupal.org/node/159605 for schema field definition


How to filter articles that have image In Views block, how do I display the articles that only have image?

How to filter it?

Update question:

1） Under Filters, add Content: Image (field_image) - list.

2)  Choose False option.

3)  Preview of block disappear.

How do I fix it?

You add a filter criteria that checks the image's file id (fid):

Content: Image (field_image:fid)

Operator: Is not empty (NOT NULL)


Drupal Webform not submitting sometimes right after clearing cache I add a webform node to another node via hook_page_alter() or in a block. Sometimes when submitting this form it doesn't submit the data and redirect to the Custom URL set in the settings.  Right after I see the
the form give me this issue I notice that the submitted data does not appear under Results -> Submissions.  It only happens right after clearing the cache. Once it happens if you refresh the page or go to another page that has the form it doesn't happen.  If I go to the actual node that is the webform I can't reproduce this issue.

Below are the steps I take to reproduce this problem (FYI I can only reproduce it sometimes. I can reproduce it logged in as user 1 but I have better luck reproducing as anonymous user):

Flush all cache via drush cc all command
Refresh page with form
Fill out form and submit
Notice that the page refreshes instead of going to destination url (this happens maybe 40% of the time)

This is how I display the webform on certain nodes via hook_page_alter():

$get_my_free_download_node = node_load($nid);
$markup = drupal_render(node_view($get_my_free_download_node, 'hcp_gmfd_slide_in'));

$page['content']['sliding_panel'] = array(
  '#markup' => $script . $markup,
);

I am using Webform 7.x-3.24.  I added debug code webform_client_form_submit() and my code never gets run when this issue happens.

I'm wondering if Varnish or Memcache is causing this issue?  I don't ever remember seeing this a long time ago but I don't think I ever did a test of clearing the cache and testing the form right away.

These are my Memcache settings in settings.php:

$conf['cache_backends'][] = 'sites/all/modules/memcache/memcache.inc';
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['cache_inc'] = './sites/all/modules/memcache/memcache.inc';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
$conf['memcache_servers'] = array('127.0.0.1:11211' => 'default');
$conf['memcache_bins'] = array('cache' => 'default');
$conf['memcache_key_prefix'] = 'AW';

$conf['reverse_proxy'] = true;
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
# Bypass Drupal bootstrap for anonymous users so that Drupal sets max-age > 0
$conf['page_cache_invoke_hooks'] = FALSE;
# Fix for admin_menu disappearing see https://drupal.org/node/442560#comment-2692220
$conf['admin_menu_cache_client'] = FALSE;

Update

I originally stated that this only happened in production but after testing locally more often I was able to replicate the issue locally.

Turns out that this issue was happening to me locally so it wasn't Memcache or Varnish that was causing this issue.  It turned out to be a webforms module.

Because I was embedding the form on another node the '#action' value was incorrect.  I didn't run into this issue in the past because the code was updated on a newer version of webforms.

One fix is to use hook_form_alter() to change the action:

if ($form["#node"]->type == "stage_one_form" && !path_is_admin(current_path())) {
  $alias = "/" . drupal_get_path_alias("node/{$form['#node']->nid}");
  $form['#action'] = $alias;
}

Another fix is to run the patch I created here.


Taxonomy term name alias in taxonomy term autocomplete I'd like to have two or more names for one Term-ID in my custom taxonomy dictionary. As for now I've added a custom field and named it "Synonyms". The field can have multiple values.

How can I display values of the "Synonyms" field in the autocomplete taxonomy widget (or even a list control) together with original names of the terms (is there any way to do this?).

Real life example:

tid  |name              |synonyms
_____|__________________|___________________________
1    |sneakers          |gym shoes, tennis shoes

The main name would be: sneakers but while tagging a user may also type: "tennis shoes" into autocomplete and it will link the node field (for example: "Shoes type") with sneakers (tid 1).

Two options to maybe investigate (neither are easy...):

You could create a custom module using hook_field_widget_form() to define a custom widget. There are several good tutorials on hook_field_widget_form out there, here's one I found quite useful, and the Form API Reference will help too. You might also want to look at Autocomplete Deluxe as a possible base.
You could create a Views table with autocomplete exposed filters, and some custom javascipt that binds a click event to each row controlling the form element, and you could use the 'Node edit' override in Ctools page manager to customise the form page and add it in. If you want one autocomplete box to filter both 'Name' and 'Synonyms', you might need some custom javascript again: maybe hide one input box and control its input with a jquery keyup event on the other box, and set the contextual filters to 'Or' in Views

Of these I'd recommend the first way - much cleaner and probably less work!


Migration with custom files path I have to migrate a website from Drupal 7 to Drupal 9.
My Drupal 7 files were located in this directory : sites/mywebsite/files
In Drupal 9, files will be located in this directory : sites/default/files
While paths are automatically managed by media module in ckeditor in D9, the path for every file is still sites/mywebsite/files/myfile.pdf. I don't know where to change it.
How to fix this?
Thanks

You can achieve that by adopting the below snippet to your use case.
source:
  constants:
    PROFILE_PICTURES_FILE_DIRECTORY: 'public://profile_pictures/'

process:

  profile_picture_destination_filename_base:
    -
      plugin: concat
      source:
        - title
        - field_account_id
      delimiter: '-'

  profile_picture_destination_filename:
    -
      plugin: callback
      callable: basename
      source: field_profile_picture # This is the photo URL column.
    -
      plugin: callback
      callable: ucfirst

  profile_picture_destination_full_path:
    -
      plugin: concat
      source:
        - constants/PROFILE_PICTURES_FILE_DIRECTORY
        - '@profile_picture_destination_filename_base'
        - '@profile_picture_destination_filename'
    -
      plugin: urlencode

  profile_picture_source_image_path:
    -
      plugin: urlencode
      source: field_profile_picture # This is the photo URL column.
  uri:
    plugin: file_copy
    source:
      - '@profile_picture_source_image_path'
      - '@profile_picture_destination_full_path'
    file_exists: 'rename'
    move: FALSE


How do i force a text format and hide the format selector in a formatted text field? I Want to force a certain text format in a user profile text format field and hide the text format selector dropdown. How do i do it? This is for Drupal 8.

Install the module Allowed Formats and configure the field to allow only one text format. Then the text format selector dropdown will no longer be displayed.


Allow special characters in the Search Form I can't search with any special character in the default search block form or in search API.
Commonly used word like B&W (black and white) don't seem indexed up well, probably due to some encoding or decoding problem.

Drupal's built-in search, as well as Search API, generally search full words.
Using Search API, you can further configure the search to match parts of words and consistently ignore special characters in the matching process (as some may reserve other purposes like logical AND / OR).

Based on your use case/example,

check the minimum character length for search suggestions (it is usually three) (but since it strips away special characters such as the &, your search criteria is only two characters), and
enable the "Ignore characters" processor and configure it to ignore the ampersand symbol, hyphens, or any others consistently in both the form submission and the search index results as suggested here in this Search API issue post: Special characters are always ignored in searches on DB backend

Additional references:

Review all the configurable Search API processors to ensure you are indexing your content appropriately: https://www.drupal.org/docs/8/modules/search-api/getting-started/processors
Check out this succinct blog post "How to set up search API for partial words in Drupal" that provides a checklist for configuring your Search Index.
Consider configuring a search view that reflects a "Single phrase" parse mode to find exact matches with special characters. This Using Search API, Search API Solr and Facets in Drupal 8 slidedeck provides a good rundown of caveats with Search API for D8.


How do I bulk delete taxonomy terms? I'm looking for a way to delete about 1300 taxonomy terms (of 5250 in total) and their association with nodes.
I firstly thought to delete the content of these tables:

taxonomy_index
taxonomy_term_data
taxonomy_ter_field_data
taxonomy_term_hierarchy
node__field_tags
node_revision__field_tag

Is this sufficient?
Is there a better way to do it, without Drush, which I cannot install?

EDIT :

I'm trying to do it programmaticaly, but I have an error

Error: Call to undefined function field_attach_delete() in delete_taxonomy_terms() (line 42 of /var/www/html/d8/delete_tags.php).

Trying to add call to module_load_include() but still get the same error.
I put the file at the root of my Drupal installation (../mydrupal/delete_tags.php).

<?php
error_reporting(E_ALL);
date_default_timezone_set('Europe/Paris');

define('DRUPAL_DIR', $_SERVER["DOCUMENT_ROOT"]); //__DIR__ ); //.'/../drupal');

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';
$kernel = new DrupalKernel('prod', $autoloader);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

/**
 * Deletes taxonomy terms.
 *
 * @param array $tids
 *   Array of taxonomy term IDs.
 */

$tids = [830];

delete_taxonomy_terms($tids);

function delete_taxonomy_terms($tids) {

module_load_include("inc", "field", "field.attach");

  db_delete('taxonomy_term_data')
    ->condition('tid', $tids, 'IN')
    ->execute();
  db_delete('taxonomy_term_hierarchy')
    ->condition('tid', $tids, 'IN')
    ->execute();

  $terms = taxonomy_term_load_multiple($tids);

  foreach ($terms as $term) {
    field_attach_delete('taxonomy_term', $term);
    module_invoke_all('taxonomy_term_delete', $term);
    module_invoke_all('entity_delete', $term, 'taxonomy_term');
  }

  // Reset static cache after all terms deleted.
  taxonomy_terms_static_reset();
}

Before you clean the vocabulary you need to change the taxonomy reference field, to do this you can use this code:

$nids = \Drupal::entityQuery('node')->condition('type','YOUR_CONTENT_TYPE')->execute();
$nodes =  \Drupal\node\Entity\Node::loadMultiple($nids);

foreach($nodes as $node) {
  // Change your term here
  $node->field_YOUR_TAXONOMY_REFERENCE_FIELD->value = '';
 $node->save();
}

To clean the vocabulary use this modification of a drush command that you can see in https://github.com/adrian-cid/drush_commands/blob/master/drush_taxonomy.drush.inc

You need to pass an array of vocabularies names to clean.

I use the dpm() function (you need to install Devel) to show the messages, but you can change it if you want.

function taxonomy_vocabulary_clean(array $names) {
  if (!empty($names)) {
    // Check for duplicate ids.
    $test_names = array_unique($names);
    if (count($test_names) != count($names)) {
      dpm('You have duplicate vocabulary names.');
      return;
    }
    //Searching the vocabularies in the site
    $vocabulary_in_db = array_keys(Drupal\taxonomy\Entity\Vocabulary::loadMultiple());
    $vocabulary_non_existent = array_diff($names, $vocabulary_in_db);
    $vocabulary_existent = array_diff($names, $vocabulary_non_existent);

    if (count($vocabulary_existent) == 0) {
      dpm("The desired vocabulary to clean doesn't exists.");
      return;
    }
    if (count($vocabulary_non_existent)) {
      dpm('Non-existent vocabulary:');
      dpm(implode(' ', $vocabulary_non_existent));
    }

    foreach ($vocabulary_existent as $name) {
      $tids = \Drupal::entityQuery('taxonomy_term')
        ->condition('vid', $name)
        ->execute();

      $controller = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
      $entities = $controller->loadMultiple($tids);
      $controller->delete($entities);
    }
    dpm('Vocabulary cleaned:');
    dpm(implode(' ', $vocabulary_existent));
  }
  else {
    dpm('You must enter at least one vocabulary name.');
  }
}

Using the function:

taxonomy_vocabulary_clean(['tags', 'my_vocabulary_machine_name']);

The Drupal 7 code:

function taxonomy_vocabulary_clean(array $names) {
  if (!empty($names)) {
    // Check for duplicate ids.
    $test_names = array_unique($names);
    if (count($test_names) != count($names)) {
      dpm('You have duplicate vocabulary names.'));
      return;
    }
    //Searching the vocabularies in the site
    $vocabulary_in_db = array_column(taxonomy_get_vocabularies(), 'machine_name');
    $vocabulary_non_existent = array_diff($names, $vocabulary_in_db);
    $vocabulary_existent = array_diff($names, $vocabulary_non_existent);

    if(count($vocabulary_existent) == 0) {
      dpm("The desired vocabulary to clean doesn't exists.");
      return;
    }
    if(count($vocabulary_non_existent)) {
      dpm('Non-existent vocabulary:');
      dpm(implode(' ', $vocabulary_non_existent));
    }

    foreach ($vocabulary_existent as $name) {
      $vid = taxonomy_vocabulary_machine_name_load($name)->vid;
      foreach(taxonomy_get_tree($vid) as $term) {
        taxonomy_term_delete($term->tid);
      }
    }
    dpm('Vocabulary cleaned:');
    dpm(implode(' ', $vocabulary_existent));
  }
  else {
    dpm('You must enter at least one vocabulary name.');
  }
}


Strict HTML strips CSS classes in a custom block I created a custom block using Strict HTML (and adding <div> and other tags to the allowed HTML). If I look at the frontend, it strips all the CSS classes like <div class="myclass">.

What do I have to do to create this block with all the CSS classes, and the custom HTML markup?

Default custom blocks in Drupal 8 use the Basic HTML text format. Using either Basic HTML or Restricted HTML will remove any class attributes.

You need to set your format to Full HTML to prevent Drupal from stripping out these attributes.


Print image with alt text In the node template, I print an image gallery. I need to add the alt text.

<div class="field--name-field_gallery">
  {{ content.field_gallery }}
  {{ content.field_gallery.alt_field }}
</div>

There are many images, which are printed, but the alt text is not printed.

How can I print it?

Print the image field in the node template like any other field:

{{ content.field_gallery }}

And then use a field twig to loop through multiple field items:

field--field-gallery.html.twig

 <div class="row expanded">
  {% for item in items %}
     {{ item.content }}
     {{ item.alt }}
    {% endfor %}
  </div>


How can I limit displayed nodes by term reference from current user? I am trying to create a view that to show content classified by taxonomy term and the hierarchy level of the logged in user within that taxonomy vocabulary.

For instance, the content is organized in 10 different levels of a taxonomy ranking, and each user is progressing through each level of that taxonomy (in an educational pathway), and we want to show all content of those levels that the user has reached and could have possibly have gone through up to that point.

For example if the user has reached level 5 (or has been given that rank by admin), the view will show all content for levels 1 through 5, but not anything higher.  If user is level 7, then the view will show all content with taxonomy 1 through 7 but nothing higher.

How can I do that? How can I reference the user in a view and take their taxonomy term to limit the view's content based on that?

To control access to your content based on taxonomy terms you need to use modules like Taxonomy Access Control or Permissions by Term. With proper configuration these will prevent users from viewing content they don't share terms with, even if they can guess the content links for example.

You can create Views that lists content based on shared taxonomy terms, but Views don't control access to original nodes pages. If a user can guess the node paths, or you have content listed on Taxonomy pages and the Taxonomy pages aren't access-controled then they will be able to see the content links there and click through.

Using one of those modules you will be able to control access through terms alone, or you may need to create a new user Role for each term, it depends on your details.

Once you solve the Permissions problem you can create Views that would show content that the current user shares terms with.

The easiest way to approach this is not to rely on weight/order at all. You can treat terms like badges: if a user reaches 3rd level, they would be tagged with the first 3 terms, and not only the third term. Drupal doesn't care if you name them "level-1" and "level-2" or "beginner" and "medium". You just have to make sure to add terms to the user once they pass a level, and keep all the terms they "collected" before.

If you go for only the one highest term they have reached you have to take care of the removing the current term when a new one is reached, it introduces complexity that isn't necessary if you're relying on taxonomy terms.

There are still ways to show only the highest term if you want to use it to rank a user.

To create a page showing content that the current user shares terms with you use Relationships to the taxonomy reference field. The details are almost the same as in this QandA: Based on user's country filter content of same country?


Term reference with radio buttons + bootstrap tooltip In the details of a user I have a term reference that is presented as radio buttons. You can select one radiobutton. The html looks like this:

        <input type="radio" id="edit-field-abonnement-und-2" name="field_abonnement[und]" value="2" class="form-radio">
        Abonnement 1

        <input type="radio" id="edit-field-abonnement-und-3" name="field_abonnement[und]" value="3" class="form-radio">
        Abonnement 2

        <input type="radio" id="edit-field-abonnement-und-4" name="field_abonnement[und]" value="4" class="form-radio">
        Abonnement 3

        <input type="radio" id="edit-field-abonnement-und-5" name="field_abonnement[und]" value="5" class="form-radio">
        Abonnement 4

But I would like to have a tooltip on each div. I can add a javascript file and send some data to the javascript and set the title with the data (I would do this with taxonomy_term_load).

But how can I get a structure like this and make sure the tooltip works?

<button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="left" title="Tooltip on left">Tooltip on left</button>

Part 1

You can theme a field, using theme suggestions:

  field--[type|name[--content-type]|content-type].tpl.php base template:

  field.tpl.php

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

  field--field-name--content-type.tpl.php
  field--content-type.tpl.php
  field--field-name.tpl.php field--field-type.tpl.php

  Note that underscores in a Field's machine name are replaced by hyphens. Also
  remember to include "field-" in custom field names, e.g: field--field-phone.tpl.php.

Get a copy of the base field theme from modules/field/theme/field.tpl.php and copy to your theme's folder, rename and modify as required.

Part 2

A better options is to use the Fences Module which allows for greater control over theming your fields.

  Fences is a an easy-to-use tool to specify an HTML element for each
  field. This element choice will propagate everywhere the field is
  used, such as teasers, RSS feeds and Views. You don't have to keep
  re-configuring the same HTML element over and over again every time
  you display the field.

All of the field tempaltes are in /sites/all/modules/fences/templates and correspond to the type of wrapper you have applied to your field.

Like part 1, copy the field you need into your theme's folder, rename and modify as required.


Showing group managers a list of pending users We're using Drupal Commons 3.3 and our group managers have been asking for a single view of all pending users. Email is becoming too cumbersome and unmanageable. Is there a View or Pane that I can add showing our Group Managers which users should become members?

First, in the View Commons Contributors - Group (User), I cloned the Display group homepage

In this new content pane, I then added a footer with a link below. This will take the user to the Administer Group/People page.

Manage memberships

Caveat: On Panels (via /admin/structure/types/manage/group/panelizer/page_manager/content), I set view permission to: Logged in User has "Approve or Deny permission for this group"


Automate hyperlink to send variables to webform Here's the background for what I'm tring to accomplish:

I am using Webform 6.x-3.11 and have a generic sign-up form located at “/project-sign-up."
The webform has a hidden field with its default value set to "%get[project-title]."
I have a custom Content-type called Project that holds data specific to various community outreach projects.

What I am trying to do is displaying a link at the bottom of each "Project" page saying "SIGN UP!" with the "href" pointing to "/project-sign-up?project=[project-title]." However, I cannot figure out how to create the link through the CCK fields of the content type. I have also tried creating a node attachment through Views UI (views_attach) to append a link (with its output rewritten) to the "Project" node, but to no avail.

Could anyone point me in the right direction?

If you are doing it in Drupal 6 then hook_nodeapi(&$node, $op, $a3, $a4) is to alter node object for additional information.

function custom_module_nodeapi(&$node, $op, $a3, $a4){
  if ($op == 'view' && $node->type == 'project') {
    $node->content['project_link'] = array(
      '#value' => l('Sign Up', 'node/[id]', array('query' => "project=" . $node->title)),
      '#weight' => 100,
    );
  }
}


node number evolution statistic? Im looking for a way to store the TOTAL number of nodes published on my drupal 6 web site at a particular month of the year so I can generate some curve from it :

timestamp | total node nb type x
2013/01   | 96
2013/02   | 100 (I mean 96+4, cumulative)
2013/03   | 120
[...]

the need seems simple to me, but I cant find any statistics module that cares about this. also the need is really simple compared to the features these modules offer.
I could write some piece of code about this using CRON and some requests to write such a table. maybe something with views count + cron.

but it certainly already exists somewhere as a module ?

thanks for any pointers/recipes.

jerome

Do you really need the publishing date? or just the created date?

If you need the former, well that date isn't tracked by core - http://drupal.org/node/1838918

You could try a contrib module to start tracking that for you... http://drupal.org/project/publication_date

If you're not worried about deleted nodes you can just do what you're after by running a query to count all the nodes that have a created date lower than month X. Or just get all nodes back, and then loop over them in php, successively incrementing counters for each month for your graph.

Otherwise, yeah you're going to have to do something with cron and get snapshots over time. I haven't heard of an existing offering for this in contrib.


How to subscribe a user to a group when the OG context is in the commerce order? I'm trying to allow people to subscribe to an organic group when buying a specific product.
The thing is that I need to set the OG context in the order, not the product or anywhere else.

Use case: The anonymous user completes an order. The site admin reviews it and then he may or may not grant the anon user the access to a specific role from a list.

How I´m trying to accomplish that:

I've installed Drupal Commerce, Rules and Organic Groups.
I create an OG audience field inside commerce orders (*og_group_ref_commerce*).
I set a rule with some conditions (if the order is set to "completed", and if the user is an anon...) and some actions (a loop to create the new user and assign him a role).

And I'm adding a special action (which doesn´t work):

Subscribe user to group

  User Data selector: account-fetched:0 Group Data Selector:
  commerce-order:og-group-ref-commerce:0

I´ve tried another way, without any success:

  User Data selector: account-created (in and outside the loop that created the user) Group Data Selector: site:og-context--node

Note: As the order doesn´t initially have the group audience context, I have to edit it in order to assign it a group. After saving it (it is still in "pending" status), I edit it again to change it to "completed".

Any ideas?

Try out following these steps

1) Using the Entity Reference module, I've created an entity reference on my product type. It's target type is "Node", and the Target Bundle is the content type of my Organic Group. In my case, that's called "Classroom".

2) I create a piece of content of type "Classroom".

3) I create a new product and a drop-down will show a list of all my Classrooms. I select one of them.

4) Now comes the time to make the rule to automatically add the user to the correct group.

Conditions
Event: Completing the checkout process

Conditions
Entity has field: commerce-order:commerce-line-items:0
.. Name of the field to check for: commerce_product

Entity has field: commerce-order:commerce-line-items:0:commerce-product
.. Name of the field to check for: field_og_reference (this is the name of my entity reference that I put on the product in Step #1).

Actions
Fetch entity by property.
.. Value: User
.. Property: Email
.. Value: commerce-order:mail
.. Limit result count: 1
.. Variable Label: Fetched Account
.. Variable Name: account_fetched

Subscribe User to Group
.. User: account-fetched:0
.. Group: commerce-order:commerce-line-items:0:commerce-product:field-og-reference:group

Solution 2
See tutorial about this, have a look:


Print module download pdf file name change characters into HTML entities I am using print module to generate pdf using dompdf library. I am facing issue with file name which node title have ampersand(&) sign, this character is converting into &amp;.

For example- If file name is hello & drupal then the file name become hello &amp; drupal - 2019-04-23

My filename filename configuration is as attached image.

I am not a specialist of dompdf, but having used fpdf, I think it's something you do in your print template or custom module that converts the fields in dompdf format.
You may need to set a php rule like this:

$title = mb_convert_encoding($title, 'HTML-ENTITIES', 'UTF-8');

Source: https://stackoverflow.com/questions/16384517/dompdf-character-encoding-utf-8

Or another one like this:

$titlePrintFriendly = preg_replace('#&amp;#',chr(38),$title);

and then print $titlePrintFriendly

I used the second one in the past to trick printing some special chars.
The dompdf library should be loaded in the file you add this line.

I took the char number from https://github.com/dompdf/dompdf/blob/master/lib/fonts/Symbol.afm


How to use Drupal.displace inside Drupal.behaviors I want to scroll down the page at page load time to bring a feature that might be below the fold into the viewport. Script works fine for anonymous, but for authenticated user, Toolbar module overlays the content I just scrolled to.

I've read that the way to resolve this is using Drupal.displace.offsets.top but when I call that from within my behavior Drupal.displace is undefined. I've been using comment-new-indicator.js from comment module as my guide here, and clearly my usecase is a little different because I'm doing this around page load time.

The problem is two fold: Drupal.displace isn't loaded when my script is called AND Toolbar hasn't done its stuff yet. I've cleared caches both in browser and drush numerous times. I've mucked with JS weights in libraries.yml -- nothing works.

One thought was to delay the initial execution with a 500 ms smudge to wait for some eventual viewport adjustment milliseconds later (that may or may not ever happen). So far this isn't really working well either, I don't want to delay the smudge longer for normal users because it becomes too noticeable.

Another thought was to register an event listener for drupalViewportOffsetChange but for some reason that never gets triggered.

mytheme.libraries.yml

custom-scroll-feature:
  js:
    js/custom-scroll-feature.js: { weight: -1 }
  dependencies:
    - core/jquery
    - core/drupal
    - core/drupal.displace

js/custom-scroll-feature.js

(function ($, Drupal) {

  'use strict';

  Drupal.behaviors.customScrollFeature = {
    attach: function (context, settings) {

      console.log(Drupal.displace);
      // outputs 'undefined'

      console.log(Drupal);
      // outputs
      // {behaviors: {…}, locale: {…}, throwError: ƒ, attachBehaviors: ƒ, detachBehaviors: ƒ, …}
      // no mention of Drupal.displace

      var start = time();
      $(document).on('drupalViewportOffsetChange', function () {
        console.log(Drupal);
        console.log(displace);
        var end = time(),
          elapsed = end - start;
        console.log("elapsed: " + elapsed);
        // The above never gets triggered.
      });

    }
  };

})(jQuery, Drupal);

With JS aggregation off, I've confirmed that jquery.js, drupal.js, and displace.js are all present in the list of requests on chrome network tab and appear before custom-scroll-feature.js is requested.

After I let the page load, and type the following into the javascript console, i get the expected value:

> Drupal.displace.offsets.top
79

To be clear I do not want to make a dependency on Toolbar, because then that would load more javascript for all users but I want to be sure that this script runs after Toolbar may have run, if it existed in the requests.  I would have thought that automagically the weight of js added by themes would be higher than that of core modules, no?

Your thought to use drupalViewportOffsetChange is the way to go. The actual event is drupalViewportOffsetChange.toolbar. Here is an example:

  Drupal.behaviors.myTheme = {
    attach: function attach(context) {
      if (context === document) {
        $(context).on("drupalViewportOffsetChange.toolbar", function (event, offsets) {
          var selectors = [".class-of-thing-i-want-to-offset"];
          selectors.forEach(function (selector) {
            if ($(selector).length > 0 && offsets.top > 0) {
              $(selector).css("top", offsets.top);
            }
          });
        });
      }
    }
  };


Can I turn cache off for the development deployment? On development platform caching can be a pain. Can I turn it off? Will it affect any of the modules that require it?

Install the devel module which adds a cache clear option for administrators.
You'll find a devel block to add to a region for quick cache clearing, or if you install the admin menu and get a quick menu in the top left for clearing various caches in Drupal.

If you like the command line install drush and use the drush cc all command to clear your sites caches. Beware that currently drush cc doesn't clear the Varnish cache if that's applicable to your setup.


whats the best way to run 2 sites but use same database with same prefix on Drupal 7? basically i want to create a duplicate of the site and place it in a separate folder to the main site on the same domain, and have both sites use the same database, so that if one site changes something it changes on the other site too

basically im gonna be developing on one version of the site, while a designer works on the design and CSS on the other site, but he may also want to edit menu links, blocks etc so he will need to be able to write to the database as admin, once both dev and styling are complete we would copy the theme folder from the designers site in to the dev site and delete the other site and use just one for launch

what would be the best way to do this?

It is quite possible in Drupal. Make sure settings.php on both the instances are identical (I assume both the instances are hosted on a single server).

However, better way to manage such a scenario is to use version control.


Multiple choice poll I thought this would be out of the box, but it doesn't seem so.

I'm looking for a way to be able to have a multiple choice poll where users can select more than one answer.

Is this even possible with the Drupal 7 Core Poll Module?

If Core Poll does not allow this, are there some other modules out there which are not in dev?

You might want to consider Webform. It functions differently from Poll, but it's also much more robust and has plenty of additional modules that extend it.

And, of course, creating a question that allows multiple choices is a snap.


Is there a module to provide node access based on Ip address? I am looking for a module that provides node access or content type access based on the ip address of the user? So what would be ideal is that i can select the ip address range allowed for a particular node when creating it or i can define a range of ip address on a content type.

Once i select the ip address range then someone coming from outside of that range should not be able to access that page.

I have looked into several modules and couldn't find much. The closest thing i found is in sandbox https://www.drupal.org/sandbox/schlicki/1461406

Please let me know if i can clarify more?

The Restrict IP  module is what you're looking for.

This module allows administrators to restrict access to the site to an administrator defined set of IP addresses.
Anyone trying to access the site from an IP address not in the list of allowed IP addresses will be redirected to an access denied page with the message "Your address is not in the list of allowed IP addresses". No blocks will be rendered, and no javascript will be added to the page. This will happen for any and all pages these users try to access.


Reload Javascript after ajax event I have a module that uses a button to load an embed view everytime the button is clicked.

// function to print builder view
    function workout_builder_template() {
        $viewName = 'builder_view';
        print views_embed_view($viewName);
    }

workout_builder_template();

However after the button is pressed a new view is loaded and the view is no long ajaxified. For example, if I click the apply button after changing the exposed forms, the form submits to a new page. Before clicking the button that loads an embed view via ajax, the exposed form altered the view content via ajax.

Here is example html from the ajaxified view

<form accept-charset="UTF-8" id="views-exposed-form-builder-view-default" method="get" action="/drupal7/builder-view" class="ctools-auto-submit-full-form ctools-auto-submit-processed jquery-once-1-processed">

Here is example html from the ajax less view

  <form accept-charset="UTF-8" id="views-exposed-form-builder-view-default" method="get" action="/drupal7/builder-view" class="ctools-auto-submit-full-form">

In the example the ajax less view does not have processed classes added to it. From this I suspect that the new view does not get javascript attached to it after the first ajax event. I have been researching drupal.behaviors and thought about printing

$vars['scripts'] = drupal_get_js();
print $vars['scripts'];

in the workout_builder_template() function displayed above, but I am not sure how this is done

I could be wrong here but am going to assume that the fetching of the embedded view and HTML refresh on the client-side has been done using custom Javascript code.

Once new HTML has been added to the DOM in a custom way, then to attach all Drupal behaviors defined by active modules, from within the success callback of your XHR client (say jQuery.ajax()) you might have to manually call:

// $wrapper here is the jQuery object identifying the wrapper element to
// which your new HTML has been injected to. Eg. $wrapper = $('.my-view-wrapper')
Drupal.attachBehaviors($wrapper, Drupal.settings);

My recommendation would be to try and possibly switch to the Drupal AJAX API (Documentation) as it lets you keep this refresh logic on the server-side (one place). The other, obvious benefit is that Drupal.attachBehaviors() is called for you automatically.


How to get translated month labels I think, this labels and its translations are available, but I don't know where. I found nothing in the "Translate Interface" seach.

So here's my question:
is there a way to get translated month labels more elegant as like t('january') ?

Normally date labels (months, day, etc. in short and long version) should be translated automatically according to the language configured for Drupal interface (admin/config/regional/settings).

However, in case there might have been an issue somewhere, with Drush and the module Localization update enabled the following command forces the translation to be updated and it solved the issue in my case:

drush l10n-update


Views : List all user who didn't publish anything Is it possible to create a list of all the user that didn't create a certain kind of content? I'm making a school graduated student album and each student have to creates a personnel node about there final projet and I need to verify who didn't create is node.

I try to create a list of all user of the student role but when I create a link whit the node with "Content authored" and I add the node Title the users without a Final Project Node hare removed from the list and this is excly the opposite that I need.

Thanks for you help.

Create a view showing Users
In Relationships add:

User: Content authored

In Filter criteria add:

User: The user ID:

operator: is not equal to value: 0 (it excludes the anonymous user)

Content: Nid:

operator: Is empty (NULL) [this gives you a list of users who have authored any content (excluding the anonymous user as mentioned above])

The exported view:

$view = new view();
$view->name = 'users_with_no_content';
$view->description = 'Displays a list of users who have added any content yet.';
$view->tag = 'default';
$view->base_table = 'users';
$view->human_name = 'Users with no content';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = TRUE; /* Edit this to false to make a default view enabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['access']['perm'] = 'access user profiles';
$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'] = '50';
$handler->display->display_options['pager']['options']['offset'] = '0';
$handler->display->display_options['pager']['options']['id'] = '0';
$handler->display->display_options['pager']['options']['quantity'] = '9';
$handler->display->display_options['style_plugin'] = 'list';
$handler->display->display_options['style_options']['row_class'] = 'user';
$handler->display->display_options['style_options']['default_row_class'] = FALSE;
$handler->display->display_options['style_options']['row_class_special'] = FALSE;
$handler->display->display_options['style_options']['type'] = 'ol';
$handler->display->display_options['style_options']['class'] = 'user-with-no-content';
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: User: Content authored */
$handler->display->display_options['relationships']['uid']['id'] = 'uid';
$handler->display->display_options['relationships']['uid']['table'] = 'users';
$handler->display->display_options['relationships']['uid']['field'] = 'uid';
/* Field: User: Name */
$handler->display->display_options['fields']['name']['id'] = 'name';
$handler->display->display_options['fields']['name']['table'] = 'users';
$handler->display->display_options['fields']['name']['field'] = 'name';
$handler->display->display_options['fields']['name']['label'] = '';
$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']['element_type'] = '0';
$handler->display->display_options['fields']['name']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['name']['element_wrapper_type'] = '0';
$handler->display->display_options['fields']['name']['element_default_classes'] = FALSE;
/* Filter criterion: User: The user ID */
$handler->display->display_options['filters']['uid_raw']['id'] = 'uid_raw';
$handler->display->display_options['filters']['uid_raw']['table'] = 'users';
$handler->display->display_options['filters']['uid_raw']['field'] = 'uid_raw';
$handler->display->display_options['filters']['uid_raw']['operator'] = '!=';
$handler->display->display_options['filters']['uid_raw']['value']['value'] = '0';
$handler->display->display_options['filters']['uid_raw']['group'] = 1;
/* Filter criterion: Content: Nid */
$handler->display->display_options['filters']['nid']['id'] = 'nid';
$handler->display->display_options['filters']['nid']['table'] = 'node';
$handler->display->display_options['filters']['nid']['field'] = 'nid';
$handler->display->display_options['filters']['nid']['relationship'] = 'uid';
$handler->display->display_options['filters']['nid']['operator'] = 'empty';
$handler->display->display_options['filters']['nid']['group'] = 1;
$translatables['users_with_no_content'] = array(
  t('Master'),
  t('more'),
  t('Apply'),
  t('Reset'),
  t('Sort by'),
  t('Asc'),
  t('Desc'),
  t('Items per page'),
  t('- All -'),
  t('Offset'),
  t('« first'),
  t('‹ previous'),
  t('next ›'),
  t('last »'),
  t('nodes'),
);


Drupal login error message display on page by make new module I created the module and added the field in the user login block form for displaying error. I want to display the error in warning field instead of using form_set_error(). I am able to see the warning field in the login block. When I submit with error it did not display the error. Code is as under. I am missing how to refresh the value of form once it gets error.

function usermoved_form_user_login_block_alter(&$form, &$form_state) {
$form['warning'] = array(
'#value' => t('oops'),
'#weight' => 11
);
$form['#submit'][] = 'usermoved_form_submit_code';
}

function usermoved_form_submit_code($form, &$form_state)
{
  global $user;
 if (!$user->uid) {
  $form['warning']['value']= "changed to something";

}

}

I have disabled the error in user.module as follows.

function user_login_final_validate($form, &$form_state) {
  global $user;
   if (!$user->uid) {
//form_set_error('name', t('Sorry, unrecognized username or password. <a
    //href="@password">Have you forgotten your password?</a>', array('@password' =>
    //url('user/password'))));
}
}

I suggest you DO NOT CHANGE DRUPAL CORE , if you want your custom validation use something like this

function usermoved_form_user_login_block_alter(&$form, &$form_state) {
   $form['warning'] = array(
   '#value' => t('oops'),
   '#weight' => 11
   );
  $form['#submit'][] = 'usermoved_form_submit_code';
  $form['#validate'][] = 'yourcustomvalidationfunction';
     }

and in your custom validate fuction  put your error in warning field

 function   yourcustomvalidationfunction(&$form,&$form_state){
    if (your validation accure error) {
        $form['warning']['#value']= t('my error message that come in warning field') ;
       }
    }

or you can  create and initial warning  directly in validation function and not require create warning field in alter


Which file should my style be in I'm putting this question in the Drupal forum rather than a CSS forum as I don't know if I just have a CSS issue or if the issue is more Drupal, maybe how I'm using the .info file.

I'm using Drupal 7 with UberCart and the AT Commerce sub-theme of Adaptivethemes.
If I put my CSS in styles.base.css they take effect. However, it I put my CSS in a separate CSS then they do not.

I edited at_commerce.info so I have this

// CSS
stylesheets[all][] = css/styles.custom.css
stylesheets[all][] = css/styles.base.css
stylesheets[all][] = css/styles.modules.css
stylesheets[all][] = css/styles.settings.css
stylesheets[all][] = color/colors.css
stylesheets[all][] = css/uc_product.css

I tried styles.custom.css as the first in the list as shown above and the last in the list and it make no difference. styles.custom.css is empty except for the 2 styles I'm trying to put there. When I put the 2 styles in styles.base.css I am putting them at the bottom of the file.

Just to eliminate a possible cause of your problem: if you have enabled CSS aggregation then you must clear the cache before changes to CSS files become active.


Drush: Make site alias read only I like having site alias defined for easy Drupal management for backing up, syncing dev site with live etc.

But I am afraid of having great loses if I mistyped the drush command having order of site aliases interchanged.

drush sql-sync @dev @live

Instead of:

drush sql-sync @live @dev

Other possibilities include:

drush rsync @dev @live

Is there any option that I can set while defining site aliases that make a site ready only in drush commands? I tried to find one, including drush source code, but didn't succeed.

Of course, outside of drush I can create separate user account that only have ready only access to the site. Also extra database user with no CREATE/UPDATE permissions.

Should be able to do it with drush_hook_COMMAND_validate().

Example: https://github.com/Lullabot/drupal-boilerplate/blob/master/drush/commands/policy.drush.inc


Reverse entity relationship I have several custom content entity types that have relationships to each another. The fields used are defined as base fields and I am using $fields['FIELD_NAME'] = BaseFieldDefinition::create('entity_reference').

Views doesn't currently implement reverse relationships for base fields, which is a feature request.

I need to define the relationship in the module with EntityViewData::getViewsData()  or hook_views_data().

Using the examples provided, I was able to define a reverse relationship for an entity reference field with cardinality of 1 (where the field is created in the entity's base_table), but I can't figure out how to do it when the cardinality is higher than 1, or unlimited (where the field is created in a separate table).

None of the examples on the documentation pages (or that I have been able to find googling)  defines a relationship between two entities that requires an intermediary table.

Views defines an EntityReverse class that I have looked at for ideas.  It has a $first_join and a $second_join.  I can confirm that if the field is added to the entity using the normal UI, then the view provides both relationships, to the related entity and the reverse relationship from the related entity.

I am not sure at all how to translate the EntityReverse class into a definition I could pass to getViewsData().

And How to do a Reverse Entity Reference? is not the answer.

Does anyone know a solution?

After some trial and error, I have been able to find a solution.

In the example code for hook_views_data(), there was a relationship example that provided this snippet.

// ID of relationship handler plugin to use.
'id' => 'standard',

Having already discovered the EntityReverse class, I was pretty sure that I would need to use 'id' => 'entity_reverse'.

The part that tripped me up the most was that I was trying to define the relationship as part of the related entity inside getViewsData() in the ViewsData class I created for the related entity.

Then it dawned on me that the documentation for hook_views_data() says:

  The return value of the getViewsData() method on the interface is the same as this hook

It means I can describe views data for any table and not just my entity's tables. Instead of trying to attach this relationship to the related entity, I tried attaching it to the main entity and this worked.

For example,

{MAIN ENTITY} is the entity being related
{RELATED ENTITY} is the entity with a relationship to {MAIN ENTITY} where {RELATED ENTITY} class has the following fields

   $fields['{FIELD NAME}'] = BaseFieldDefinition::create('entity_reference')
     ->setSetting('target_type', '{MAIN ENTITY}')
     ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) // or a specific number higher than 1

The getViewsData() method of the ViewsData class for {RELATED ENTITY} is the following.

public function getViewsData() {
  $data = parent::getViewsData();
  $data['{MAIN ENTITY BASE TABLE}']['{useful non-conflicting name - I used the {RELATED ENTITY BASE TABLE}}'] = [
    'title' => t('{some useful title that displays in Add Relationships popup}'),
    'help' => t('{some useful description that displays in Add Relationships popup}'),
    'relationship' => [
      'field_name' => '{name of the field - same as {FIELD_NAME}}',
      'field table' => '{name of intermediary table - it is probably {RELATED ENTITY}__{FIELD NAME}',
      'field field' => '{name of intermediary field - it is probably {FIELD NAME}_target_id',
      'base' => '{RELATED ENTITY BASE TABLE}',
      'base field' => '{RELATED ENTITY ID FIELD}',
      'id' => 'entity_reverse',
      'label' => '{some useful label that displays in Relationship select in various views field settings popups}',
    ],
  ];

  return $data;
}


drupal_add_js weight I've written a javascript that for some reason whenever I run it, it removes any hover events.  Since I am running my site with nice menus I would like to run my script as high up in the $script array as possible.

I added this line to the template.php:

drupal_add_js('sites/itascacg.com/themes/custom/icg/js/fixtitles.js',array('type' => 'file', 'weight' => -19));

since according to the documentation I've read jQuery itself is at weight -20, but no matter what weight I give my script i won't float any higher on the list.

does anybody have anybody have any ideas how to push my script up, or at worst push all the other scripts down?

P.S. I'm using drupal 7

In what function in template.php are you adding this? A preprocess function I hope.

Anyway, you have to set the 'group' option as outlined on the drupal_add_js page. eg.

drupal_add_js('sites/itascacg.com/themes/custom/icg/js/fixtitles.js',array('type' => 'file', 'weight' => -19, 'group' => JS_LIBRARY));


How to get the nid of nodes created by user (on the event of logout)? I have a  content type 'XYZ' for which the user has created nodes. Is there any way I can use to get the node ID of all the nodes created or deleted by user at the time of logout?

I am using hook_user_logout(), but I am not able to get the node IDs for the node created by the user.

hook_user_logout() is probably called only when the user uses user/logout to log out. If users don't log out all the times after they used the site, that hook is probably not going to be invoked. (For example, I have never logged out from Drupal.org, and I log in back once my session expires for the browser I am using.)
Furthermore, once a node is deleted, there is no track of it in the database, and since hook_user_logout() is going to be eventually invoked when it is too late, it is not going to find any information about the nodes deleted by the user.

I would rather use hook_node_insert() and hook_node_delete() to collect the data that will be used from another hook. For example, the following code would work.

function mymodule_node_insert($node) {
  $_SESSION['created'][$node->nid] = TRUE;
}

function mymodule_node_delete($node) {
  $_SESSION['deleted'][$node->nid] = TRUE;
}

If that is helpful information, instead of TRUE you can use REQUEST_TIME; in that way, you would log when the user created or deleted a node.

Eventually, you can use a database table instead of a session variable, but in that case you should clean it after the user logged out, if you want to reset the information you collected once the user logs out. With the code I shown, you would lose the information when the session expires for the user, so it is probably preferable for you to store the information in the database.

The method suggested by the other users doesn't work when the user creates a node and deletes it. Counting the number of nodes associated with a user ID doesn't include the nodes that have been deleted before the user logged out. Also, since users with the permission of administering nodes can associate a node with a user different from the user who created it, counting the nodes associated with a user ID is going to give wrong information.


Retrieve data from Field API programmatically I have a custom field called phone_number for the user. I need to retrieve the data in it from the database and use it to call other functions. I've looked through the Field API and I can't find the specific function. I read somewhere in the Field Attach API that most of the functions there take $entity as a variable but none of the functions there gives me what I need. Please help.

Use Field data extraction API module to accomplish your job of field data extraction.

As per the documentation, you have to write this in yourmodule

  $phonenumbers = field_extract_values('node', $node, 'phone_number');

  $result = someCustomFunction($phonenumbers);

  function someCustomFunction($user_phonenumbers){

   // Do something here and return value

   }


Why isn't my new module listed in the list of modules? I am trying to build a new module, but, it is not listed in the list of modules.

This is the content of the add_new_chapter.info file:

;$Id$

name = Chapters field
description = Will create a field that will refrence a node of type chapter type
package = Online School Development
core = 7.x
files[] = add_new_chapter.module

I placed the add_new_chapter.info file in the directory "add_new_chapter" at
drupalroot/sites/all/modules/add_new_chapter.

what I expect is to see a new category ("Online School Development") in the page listing the modules but it doesn't get listed.

I tried to clear the Drupal cache, but the module didn't get listed too.

The first things I would check:

Permissions settings of the files (chmod - chown)
Remove a module to see if it has any effect


Error when upgrading to Drupal 8.7.1 on module menu_link_content When running database updates (on domain.com/update.php) from 8.6.15 to 8.7.1, I got the following error:

module menu_link_content
Update make_menu_link_content_revisionable
Custom menu links have been converted to be revisionable.
Failed: InvalidArgumentException: Placeholders must have a trailing [] if they are to be expanded with an array of values. in Drupal\Core\Database\Connection->expandArguments() (line 735 of /baseserverpath/public_html/web/core/lib/Drupal/Core/Database/Connection.php)

I can see the error "Placeholders must have a trailing [] if they are to be expanded with an array of values" happens on several different occasions in Drupal 8, as there are some different posts on the issue dating back to 2016. But I cannot find it related specifically to module 'menu_link_content'. I wonder if the problem could be related to a special character that cannot be correctly escaped.

The upgrade doesn't work and some other database upgrades get stuck in the queue, since this one for 'menu_link_content' cannot be completed.

I got this error, but when I had run the update with drush updatedb -y command, I resolved that.


Display content type in custom display format I created an content type of name "profile", where it has fields
Profile Name, Image , message , body.

It displays in this format attached image_1

Now how can we arrange or make change in custom format like below image image_2
how can we displayed to end user

you can use node--NAMECONTENTTYPE.tpl.php in your directory template. Please see this documentation and comments about templates in Drupal 6 http://drupal.org/node/17565, this will give you a guidance to recognize some few differences with Drupal 7.

to be more detailed, you can copy/paste to your theme directory the file node.tpl.php (located in modules > node or already located inside your theme directory) and rename it according your content type. for example, if the Content Type is Article the name will be node--article.tpl.php

already inside in node--article.tpl.php you can see the variable $content or you can use $node. $content (or $node) variable is carrying the content of your node. you can use print_r($content); to see the list of the fields that you can use to your node (or if you use Devel module, is best use dsm($content);)

see this example:

I have a field called field_demotext1, then this is the way that I can use to call their respective value inside any custom html zone of my node layout:

echo $content['field_demotext1']['#items'][0]['value'];

here is the example of zone in the node--article.tpl.php where you can use a custom html:

  <div class="content clearfix"<?php print $content_attributes; ?>>
    <?php
      // We hide the comments and links now so that we can render them later.
      hide($content['comments']);
      hide($content['links']);
      //print render($content); comment to hide all content
      echo $content['field_demotext1']['#items'][0]['value']; //will only show field_demotext1 value
    ?>
  </div>


Search additional user fields? When using the search form, by default Drupal searches Content nodes, and there's a toggle to search Users (search/node vs. search/user). But the search/user appears to only search the default fields for the User nodes (username and email). I've added additional fields (Admin > Config > People > Manage Fields) to User nodes, but those don't get searched. How can I make the default search/user find users by those additional fields?

As far as I know, the easiest way to do this is with views. You can set up a user view with exposed filters for any user field that you need to search. If you want to get a link to your your view on the search page form then, a form alter in a custom module would do it. Obviously make sure your view has a page with a proper path setup. search/your_view etc will work.

Here is a quick example of adding a custom markup field to the search form in drupal 7.

function CUSTOMMODULENAME_form_alter(&$form, $form_state, $form_id) {

 if ($form_id == 'search_form') {

   $form['usercustomsearchlink'] = array(
  '#type' => 'markup',
  '#markup' => 'Search User Fields ',
  '#weight' => 1,
   );

   }
}

That should put a link underneath the search box on the form (after a cache clear). However, I havent been able to figure out how to make it appear only on search/user pages yet so, that link will appear on all search forms.


Colorbox after ajax load I've created a custom module that updates content in my page via an ajax call.  I tried it do it with only views but it was too complex because I was loading multiple content types based on organic groups.

So I have a view that I'm rendering from code and in that view I have a colorbox trigger.  The ajax works and the view gets rendered but I cannot figure out how to properly process the inline-colorbox.  Right now it seems to create the colorbox but fills it with default content from the frontpage so I'm not sure what I'm missing.

I re-init the colorbox after the ajax is loaded in the success and it does process the field.

JS Code

(function ($) {
Drupal.behaviors.forums_dashboard = {
attach: function (context) {

  // If changing the select field
  $('#cohort-select-value', context).change(function () {
        var cohort = $(this).val();
        var dataString = "cohort=" + cohort;

        $.ajax({
          url: '/ajax/coaching_summary',
          type: "POST",
          data: {cohort_id: cohort},
          success: function (response) {
            $('#coaching_summary_ajax').html(response);

            //reinit the colorbox
            $('.colorbox-inline').colorbox();
          }
        });
      }
  );
}
}
})(jQuery);

Ajax code in my module:

function forums_dashboard_menu() {
// Ajax callback
 $items['ajax/coaching_summary'] = [
  'title' => 'Update Coaching Summary',
  'page callback' => 'forums_dashboard_update_coaching',
  'access arguments' => ['access content'],
  'type' => MENU_CALLBACK,
 ];
 return $items;
}

function used to print the view is:

print views_embed_view('cohort_user_list','default',$args);
drupal_exit();

here is the html i get after ajax is called

Edit: I forgot to add versions
Drupal 7.56
Colorbox 7.x-2.13
Views 7.x-3.18

Update:  I decided to use a separate page view for the content to load instead of trying to do it inline.  Here is the new cleaned up jquery

(function ($) {
Drupal.behaviors.forums_dashboard = {
attach: function (context, settings) {

  // If changing the select field
  $('#cohort-select-value', context).change(function () {
    var cohort = $(this).val();

    $.ajax({
      url: '/ajax/coaching_summary',
      type: "POST",
      data: {cohort_id: cohort},
      success: function (response) {
        $('#coaching_summary_ajax').html(response);
        $('a',context).colorbox();
      }
    });
  });
}}}(jQuery));

The ajax now returns it as follows to create the URL for a colorbox-node link instead which links to the page with the UID as a parameter:

Test User 1

100 Hours

My problem now is that the first time I click the link it displays the entire page with header/footer instead of just the node content which colorbox-node should be doing.  If I close the colorbox and click the link a second time it displays only the node content as expected.  The colorbox URL gets updated when its clicked the first time.  I'm not sure how to replicate this colorbox process so that it works the first time as expected.  Here is the new link after its clicked a first time.

Test User 1

100 Hours

Here is the updated jquery code that renders the colorbox properly the first time:

success: function (response) {
        $('#coaching_summary_ajax').html(response);
        $('.colorbox-node',context).once('init-colorbox-node-processed',function () {
          $(this).colorboxNode({'launch': false});
        });
        $('.colorbox-node',context).colorbox();

      }


How to speed up Batch API processing Ok, so I've got a script that's going to go through about 13000 nodes (which might be part of the problem, but I don't think it is).

I can either put them as one large array, which seems to go through the nodes fairly quickly, but eventually leads to a timeout after 600 seconds (10 minutes).

My batch is being produced with this code:

function revision_published_lr_build_batch($items) {

   $count_items = count($items);

    $i = 0;

   foreach ($items as $item) {
    $i++;
    // Here we can add multiple operation using an array variable.
    $operations[] = array('revision_published_process_data', array($item, 'details' => t('(Importing item @item  of  @count)', array('@item ' => $i, '@count' => $count_items)))); // operation with argument
    }
  //$operations[] = array('revision_published_process_data', array($items, 'details' => t('(Importing items)')));
  //Define your batch operation here
  $batch = array(
    'title' => t('Batch operation process'),
    'operations' => $operations,
    'finished' => 'revision_published_lr_build_batch_finished',
    'init_message' => t('Initializing...'),
    'progress_message' => t('Operation @current out of @total.'),
    'error_message' => t('Found some error here.'),
  );

  return $batch;
}

Each batch item should be just an MD5 hash.

However, when going through everything, it is taking forever - the process has been running for hours and it is only on the 86th or so node.

Note, the ONLY major difference in speed appears to be whether or not I put in the foreach loop and create a lot of different operations, or whether I just put $items straight into the operations variable.

Why would this difference cause such a marked speed difference? Batch API seems like it would be more suited to work with lots of small items, rather than one big one.

I suppose one solution would be putting 100 nodes in one batch item, increasing speed for processing and decreasing the probability of a timeout during processing, but this seems like an inelegant solution.

So in short - how do I make batch API process faster?

To clarify, changing the code to this (and removing the foreach loop) is what makes processing faster (but eventually leads to a timeout because the processing is all happening at once):

$operations[] = array('revision_published_process_data', array($items, 'details' => t('(Importing item @item  of  @count)', array('@item ' => $i, '@count' => $count_items))));

You're asking alot of questions ... here are some general answers.

The batch api is used to take a set of data and partition out the data into workable batches. The batch api does not guarentee that timeouts will not occur. you need to find a batch size that that is the sweet spot for your dataset size.
typically you would choose a batch size of say 5, 10, 15 or 20 items. and called node_save for example 25 times before going onto the next batch (page refresh). The page refreshes per batch do slow down your import process ... due to the HTTP requests.
if you're querying data say from a Queue or something if you can try to avoid re-fetching the data and using a static php variable to store information you can save some time.
The Migrate module is designed to solve these kind of problems by using Drush.

If ordering of the data doesnt matter. I find parallelizing (eg, multiple worker threads) can help with these types of imports look at Background Process and Ultimate Cron Queue Scalar.


How to speed up Reference module's Views plugin? I have a 'Node reference' field via the References 7.x-2.1 module which is pointing at a View which returns up to ~5000 results. I'm also exposing this field as a filter in a separate View. The issue that I'm having is that these ~5k results are taking up to 20s to render, despite only 10 rows being shown to the browser.

Judging by XHProf's results, I thought the best way to do this was to cache the rendered results of the referenced View. That brought the time for references_plugin_display::render down from 20s down to 10s, but that still seems like a long time. The References module doesn't seem to have documentation.

Is there a way to skip rendering 'Node reference' options, or to generally speed this process up? If the solution is to change modules, is there a migration path from D6 References fields to the new module in D7?

I wound up replacing references_plugin_style with a custom, bare-bones plugin style in my_references_plugin_style.inc:

/**
 * @file
 * Handler for my_references_plugin_style.
 */
class my_references_plugin_style extends references_plugin_style {
  function render() {
    if (!empty($this->options['grouping'])) {
      throw new Exception(t('References list (fast) does not support grouping.'));
    }

    $options = $this->display->handler->get_option('references_options');

    // Play nice with View UI 'preview' : if the view is not executed through
    // _*_reference_potential_references_views(), just display the HTML.
    if (empty($options)) {
      // "Render" rows quickly
      foreach ($this->view->result as &$row) {
        $row = $row->node_title;
      }

      $function = new ReflectionMethod('views_plugin_style', 'render');
      return $function->invoke($this);
    }

    // Foreach supposedly has better performance than array_map
    // @see http://stackoverflow.com/questions/18144782/performance-of-foreach-array-map-with-lambda-and-array-map-with-static-function
    $results = array();
    foreach ($this->view->result as $input) {
      $results[$input->nid] = array(
        'rendered' => $input->node_title,
        'group' => '',
        'title' => $input->node_title,
      );
    }

    return $results;
  }
}

Then registering it with:

/**
 * Implements hook_views_plugins().
 *
 * references.module's references_style plugin was way too slow (110s to render ~5k rows),
 * so fork that style plugin and strip most of the functionality away.
 */
function my_views_plugins() {
  $plugins = array(
    'style' => array(
      'my_references_style' => array(
        'title' => t('References list (fast)'),
        'help' => 'Returns results as a PHP array of names + rendered rows. (Less bloat than "References list").',
        'handler' => 'my_references_plugin_style',
        'theme' => 'views_view_unformatted',
        'uses row plugin' => FALSE,
        'uses fields' => TRUE,
        'uses options' => FALSE,
        'uses grouping' => FALSE,
        'type' => 'references',
        'even empty' => TRUE,
      ),
    ),
  );
  return $plugins;
}

And including the .inc file in my module's .info file:

files[] = views/my_references_plugin_style.inc

Finally, I went to my Views' UI and updated the Formatter to the new "References list (fast)" format.


Implementing i18n string translation in a custom module? I have a custom module I've built which essentially acts as a repository of custom CTools keywords that users can arbitrarily define. The issue I'm facing is I need to be able to translate these user-defined strings, so I think I need to implement string translation using the i18n_string module.

I have never worked with translation or localization before, so I'm a bit lost with regards to going about how to implement this. I think I'm on the right path with i18n_string though. Can someone experienced with i18n provide examples that I can look at so I can learn the proper way to implement this?

Exactly, you can't wrap variables with t(). They will get printed, but they won't be translatable. I had a form that saves a user-defined string and wanted that string to be translatable from Drupal's translation interface.

Messed around quite a while with i18n_string() and its attribute $name (a $textgroup and a $context glued together with :).

Finally got it: You can provide your own $textgroup via hook_i18n_string_info() and later provide any other custom string as $context (maybe take your module's name to keep things clean).

If you have more than one string in your module pay attention to have every single one of them glued with another custom string to the prior context (textgroup:context:string_1, textgroup:context:string_2, ...).

Here comes a working example:

/**
 * Implements hook_i18n_string_info().
 *
 *   This is the most interesting thing here. You create a new
 *   textgroup your strings will be identified with. Here it's
 *   simply: Custom modules.
 *   When you set the i18n-string later you then only add another
 *   string as context like 'custommodules:any_other_string'.
 *   See the markup example in the form below.
 */
function MYMODULE_i18n_string_info() {

  $groups['custommodules'] = array(
    'title' => t('Custom modules'),
    'format' => FALSE,
    'list' => TRUE,
  );

  return $groups;
}

/**
 * Example form.
 */
function form_example() {

  // Just for testing, the first form element prints the translated
  // string, so you simply can test it after translation by switching
  // your page's language and see it working. This also demonstrates how
  // you will print the string everywhere else.
  $form['markup'] = array(
    '#markup' => i18n_string('custommodules:MYMODULE:string_1', variable_get('user_defined_string', 'Bempo Kohm'), array('update' => TRUE)),
  );

  $form['string'] = array(
    '#type' => 'textfield',
    '#title' => t('A beautiful and pure string'),
    '#default_value' => variable_get('user_defined_string', 'Bempo Kohm'),
  );

  $form['button'] = array(
    '#type' => 'submit',
    '#value' => t('Action'),
  );

  return $form;
}

/**
 * Example form submit handler.
 */
function form_example_submit($form, &$form_state) {

  variable_set('user_defined_string', $form_state['values']['string']);
}


How can I build an FAQ Page with sections? I am seeking to build an FAQ page that covers a few different types of topics, thus creating a need for sections, preferably with links. Like below:

I am using Drupal 8 and have the FAQ Field module installed. I'm having trouble creating a content type since I cannot add the FAQ Field multiple times to the same content type. Does anyone have any ideas?

As an alternative to the FAQ Field module, you may want to use the Views Accordion module instead (for which an official release for D8 is already available), and its related Community documentation.

By "grouping fields", the group header can be used as accordion header. In your case, just use your "Sections" (like General, Printing, Binding) as those grouping fields. Obviously, you'd have to have a regular field (like a select list field) to actually indicate for each question in your FAQ what the actual Section for it should be.

With this approach, you have the full power of Views available to make your FAQ look like you'd want it to look.


How can I set a variable based on the render element $vars[‘body’][‘#object’][‘vid’]? In trying to learn about theming and alter hooks. I'm looking at the render array passed to hook_node_view_alter() with the following code.

function hook_node_view_alter(&$build) {
  dpm($build);
}

I want to set a variable based on $build['body']['#object']['vid']), but I get this error:

  Fatal error: Cannot use object of type stdClass as array

I don't understand this error. Can someone explain it?

The #object in the $build array is an object, therefor it's properties have to be referenced with an arrow, ->

$orig_vid = $build['body']['#object']->vid;
$build['body']['#object']->orig_val = $orig_vid;
$build['body']['#object']->vid = 100;

thanks Gulok for answering this