How to create custom placeholders on hook_menu, like "%node"? For example, for menus like /node/%node:
when /node/1 is accessed, drupal automatically translates 1 as node_load(1);

I wanted to create something like /path/%student where, when /path/1 is accessed, I could translate 1 into student_load(1);

In order to use a placeholder like %student, you need to define a student_load() function in your module, or an enabled module should define such function. Drupal automatically uses that function when the placeholder is used; that is the reason why you should avoid any conflict between the used placeholders and the existing functions.

In your case, you should use code similar to the following one.

function student_menu() {
  $items['path/%student'] = array(
    'page callback' => 'student_page',
    'page arguments' => array(1),
    'access callback' => 'user_access',
    'access arguments' => array('see student page'),
  );

  return $items;
}

function student_load($id) {
  // Load information from the database; return FALSE in case of error, or when the equivalent database row is not found.
}

function student_page($student) {
  // $student is the value returned from student_load().
  // …
}

Reference

Dynamic argument replacement (wildcard)
Wildcard usage and core's wildcards


Drupal 301 redirects for matching paths without .htaccess I am using a Drupal site on top of nginx, and would like to be able to redirect a set of pages from an old style url, to a new one, using 301s. The content has already been migrated over to the new urls, but there may be links elsewhere with the old style. How can I achieve 301 redirects for matching paths, to redirect using part of the information from the old url to inject into the new one (namely [timestamp]).

From:

example.org/article/[timestamp]

To:

example.org/article/doi/static-[timestamp]

I know how I would do this with .htaccess, but is there a way to do this in Drupal itself, or a module to achieve this?

Having looked at the docs, I think that

drupal_goto($path = '', array $options = array(), $http_response_code = 301)

May be the best way to go, with a corresponding (pseudocode):

if path == oldpath,
    drupal_goto(etc.)

Probably the Global Redirect module suits your needs.

You may have to implement the timestamp feature as a new token with a custom module.


How to alter a form's name attribute I'm trying to override the Drupal Login form. I have been able to unset and modify pieces of it, but the last thing I am struggling with is the name attribute on the submit button. Currently, the button looks like this:

 <button class="btn btn-default form-submit" id="edit-submit" name="op" value="Log in" type="submit">Log in</button>

I am trying to get rid of the name attribute, but I don't see it listed as a array element when I dpm($form). How do I alter this

EDIT:
I almost figured it out. I found that the below can be used to alter the name attribute, but I cant remove it, even if I set it equal to NULL. When set to null, it defaults to 'op':

$form['actions']['submit']['#attributes']['name'] = 'submit';

It's possible that "op" is a default that gets applied if there's nothing already there.

Try:

$form['#submit']['#attributes']['name'] = 'thing-you-want-to-call-it';


Media + WYSIWYG or ICME + CKeditor I need to build quite feature rich set of tools for file & media management both for embedded and stored files in a new D7 project. Media will be added to both fields and in the WYSIWYG and File manager is a must.

In the past I have always been working with a combo of CKeditor, IMCE, CKeditor Link, FileField Sources.

However there seems to be a lot of buzz around TinyMCE via the WYSIWYG module and Media modules. In short what am I missing out on with these new projects? They seem to have a big overlap on the above and was wondering if people have experience with both...

Should I be looking to change my toolset to WYSIWYG / Media combo?

Pantheon is now offering Panoply, a distribution built on Panels that features TinyMCE via WYSIWYG as well as the media module already set up and ready to go.  You can register for a free account with them and test out a pre-built version of Drupal with the modules already set up in a fairly intelligent configuration.

Disclaimer: I'm a Pantheon customer, but I really do think that trying out this distro is a great way to see a hands-on example of what can be done not just upon installing a bunch of modules but after someone has taken the time to polish up the site.


"Node Picker" for custom module? I'm building a custom module so the editors at my company can select several nodes and spit them out as a newsletter. There are some modules that get me halfway, but due to some specific requirements, coupled with me really wanting to wrap my head around creating custom modules, I'm starting from scratch.

I understand the hooks, and have set up the menu, permissions, and most of the form fields where users can select a template and other options. I'm stuck at the part where they actually pick the nodes.

I was thinking I can probably create a View with some exposed filters and maybe hook into that, if it's possible. Ideally, I'd let them drag and drop the nodes, reorder them, etc.

I'm not looking for someone to code this out for me, would just like to be pointed in the right direction.

Without knowing the full scope or what modules/custom code you've already developed, this could be done fairly easily with a hook_menu, custom form and a content type. The new content type would have a multi-select (probably auto complete) node reference field which will allow for simple reordering. You could then implement a hook_menu with a custom form returning all the newsletters in a select list and when the form is submitted you can use node_load() to get all the referenced nodes from the selected node. Your submit handler would pass the applicable values to whatever batch mail module/functions you're using.


How to programmatically set a custom field? I am trying to programmatically change a custom field in a user object and I'm having very little success. I want to just use a function to set the field for the object, like field_get_items, except a setter version.

It seems like I could do:

$account = user_load($GLOABALS['user']->uid);

$edit = array(
    'field_custom' => array(
        'und' => array(
            0 => array(
                'value' => $lead_id
            )
        )
    )
);

user_save($account, $edit)

But there must be a better way to do this.

Any help would be appreciated. Thanks!

Use the Entity module wrapper.

  The entity API provides some wrapper classes you may use to easily deal with entities and to leverage the entity property information modules provided. With the help of the wrappers you can access the property information, loop over known properties, or just get/set the described data values, etc.

Install the Entity module and do something like:

$user = user_load($GLOBALS['user']->uid);
$obj = entity_metadata_wrapper('user', $user);
$obj->field_custom = $lead_id;
$obj->save();

$GLOBALS is http://php.net/manual/en/reserved.variables.globals.php


custom checkout pane submission I'm using Drupal Commerce (7.x-1.4) + Commerce Coupon (and old version 7.x-1.0-beta6)

I'm using a custom checkout pane to handle my coupons redeem (we have a particular usage of coupons) and manually call the coupon redeem function after checking some stuff.

It works perfectly fine except that i cannot figure out how to make sure my custom pane form submit button doesn't trigger the whole form (and trigger all the checkout pane validations), but only my particular form

    function hook_my_pane_checkout_form($form, &$form_state, $checkout_pane, $order) {
    $order = $form_state['order'];
    $pane_form = array();
    $pane_form['ticket_code'] = array(
        '#type' => 'textarea',
        '#title' => 'Tickets',
        '#description' => 'Blahblah',
        '#rows' => 10,
    );

    $pane_form['submit_ticket'] = array(
        '#type' => 'button',
        '#value' => t('Submit my tickets'),
        '#validate' => array('_my_custom_ticket_validate_order'),
        '#submit' => array('_my_custom_ticket_submit_order'),
    );

    $pane_form['coupon_code'] = array(
        '#type' => 'textfield',
        '#title' => 'Coupon code',
        '#description' => 'Enter your coupon',
    );

    $pane_form['submit_coupon'] = array(
        '#type' => 'button',
        '#value' => t('Use my coupon'),
        '#validate' => array('_my_custom_coupon_validate_order'),
        '#submit' => array('_my_custom_coupon_validate_order'),
    );

    return $pane_form;
}

So this works ! Except that when I click on one of the submit button, it triggers the validation of the other checkout panes on the page.

I would like to prevent this as the user is redirected to the same page after using his coupons / tickets anyway.

How can I prevent this ?

Many thanks !

The short answer is you can't do what you want, but there are other things you can do. You need to look into using the #ajax properties of form elements to submit data to the server when the customer clicks your button without initiating a POST redirect as you would for a full form submission.

However, that will still trigger a validation of the entire form, not just the pieces that you specifically want to validate. What Drupal allows you to do is limit validation errors from resulting in form errors when the form is rebuilt.

The topic is honestly a big bigger than can be answered here, but I hope this points you in the right direction. The best thing to do will be to investigate how a module with similar functionality achieves what it is you want to do and imitate the code (if it's up to date and / or well-maintained ; ).


Get an Error with rendered page content in custom template file The code below works, but when I try to add the line  in my MYMODULE-page.tpl.php the content is rendered twice with some errors. For example the $title is printed, but i get an error message that the $title is not set and when I add some test text in the template file i get it also twice. I didn`t find any solution for this.

**** EDIT ****

function MYMODULE_theme() {
  return array(
    'page-MYMODULE' => array (
      'path' => drupal_get_path('module', 'MYMODULE') . '/templates',
      'template' => 'page-MYMODULE',
      'render element' => 'page',
    ),
    'content-MYMODULE' => array (
      'path' => drupal_get_path('module', 'MYMODULE') . '/templates',
      'template' => 'content-MYMODULE',
      'render element' => 'page',
      'variables' => array (
        'title' => NULL,
        'path' => NULL,
      ),
    ),
  );
}

function MYMODULE_preprocess_page(&$variables, $hook) {
  if (arg(0) == 'MYMODULE') {
    $variables['theme_hook_suggestions'][] = 'page-MYMODULE'; //underscores doesn't work for me
  };
}

function MYMODULE_menu() {
  $items = array(
    'MYMODULE' => array(
      'title' => 'Page Title',   // -> page-MYMODULE.tpl.php
      'page callback' => 'MYMODULE_page_main',
      'access callback' => TRUE,
      'type' => MENU_CALLBACK,
    ),
  );
  return $items;
}

function MYMODULE_page_main() {
  $path = drupal_get_path("module", "MYMODULE");
  $page = array();

  $page['MYMODULE'] array(
    '#theme' => 'page-MYMODULE',
    '#path' => '$path',
    '#title' => 'Content Title',  // -> content-MYMODULE.tpl.php
    '#attached' => array (
      'css' => array (
      'type' => 'file',
      'data' => $module_path.'/css/layout.css', //works only if layout.css was disable by hook_css_alter()
      'weight' => 'CSS_THEME',
     ),
  );
  return $page;
}

function MYMODULE_css_alter(&$css){
  if (arg(0) == 'MYMODULE') {
    foreach($css as $key => $val){
      if ($val['group'] == '100') {
        unset($css[$key]);
      };
    };
  }
}

page-MYMODULE.tpl.php

<?php print $title; ?>

<div id="content">
  <?php print render($page['content']); ?>
</div>

content-MYMODULE.tpl.php

<?php print $title; ?>
<?php print $path; ?>

You haven't passed a variable named $title to the template, so one won't be available.

To do so, add variables to your hook_theme implementation:

function MYMODULE_theme() {
  return array(
    'MYMODULE-page' => array(
      'path' => drupal_get_path('module', 'MYMODULE') . '/templates',
      'template' => 'MYMODULE-page',
      'render element' => 'page',
      'variables' => array('title' => ''),
      ),
    ),
  );
}

and in your page callback:

return array(
  '#theme' => 'MYMODULE-page',
  '#title' => 'Title here',
);


How to assign a content type to a workflow programmatically? is there any way that by code can assign a type of content to a workflow? I have reviewed the workflow module but I have not managed to find a method or a service that allows me to do it.

What I am trying to emulate is the action that makes this modal (programmatically not visually):

The only way I have found is by manipulating the workflows.workflow.myworkflow.yml

Per I'm trying to find a cleaner way.

Does anybody have an idea?

I found a way, I would like to know your opinion about how to do it.

No doubt you have to take into account additional validations, but basically to save a type of content to a workflow would be something like this:

/** @var \Drupal\workflows\WorkflowInterface $workflow */
$workflow = $this->entityTypeManager->getStorage("workflow")->loadByProperties(["id" => "editorial"])["editorial"];
$config = $workflow->getTypePlugin()->getConfiguration();
$config["entity_types"]["node"][] = "article";
$workflow->getTypePlugin()->setConfiguration($config);
$workflow->save();

At the moment I'm just setting contents types, for blocks it's something similar.
Greetings.


Why won't my images appear inside buttons? In the page displayed, there is a row of buttons that each say "Submit Query."

The HTML for one of these buttons is:

<INPUT TYPE="image" SRC="../images/OneLine30px.png" CLASS="select-button" ID="OneLine">`

I've also tried slightly modifying the paths to these images. This HTML is in a .tpl.php file which is inside the templates directory. The images directory is a sibling of the templates directory.

Why is Drupal displaying "Submit Query" instead of the image?
How can I get Drupal to display the images?

I'd strongly advise to use CSS for this, it's much more easier to apply and you won't hit path related issues.


Drupal views relationships to an indirect referenced contenttype I want to create a view with a field which shows an indirect referenced contenttype (see Design) using Drupal 6.

I have 3 content types: Person, Organization and Workgroup.

Each person is related to only one organization by the node reference field: field_related_org_unit.
Multiple persons can be linked to the same organization.

Each workgroup is related to only one organisation by the node reference field: field_supported_org. Multiple organizations can have the same workgroup.

Now I want a view which displays the information of a certain person (firstname, lastname) and in the same view I wan to show the workgroup which he is indirect related to (sharing the same organization).

So say, Person A is related to organization XYZ.
Workgroup B is related to organization XYX.
I want to show the title of Workgroup in the view.

I tried several relationships in the View, but couldn't get it working.
 see Setup View

Is it possible to realize this kind of setup? Could someone help me out?

The node reference fields in both the person and the workgroup both point to the same organization. Set up a relationship between person and workgroup on the organization field. That should make the workgroup name available to the view.


How do I show the last created node in a block, without using Views? How do I show the last created node in a block, without using the Views module?

The recommended way would be to create a custom module that will find/load the node and display in a block. Assuming Drupal 6 from your previous questions.

In your custom module:

<?php
/**
 * Implementation of hook_block()
 */
function YOURMODULE_block($op='list', $delta=0, $edit=array()) {
  switch ($op) {
    case 'list':
      $blocks[0]['info'] = t('Last Node Created');
      return $blocks;

    case 'view':
      // Get the last created node
      $nid = db_result(db_query('SELECT MAX(nid) AS nid FROM {node}'));
      $node = node_load($nid);

      // Add subject/content to block
      $blocks['subject'] = t('Last Node Created');
      $blocks['content'] = theme('YOURMODULE_node_last', $node);
      return $blocks;
  }
}

/**
 * Implementation of hook_theme()
 */
function YOURMODULE_theme() {
  return array(
    'YOURMODULE_node_last' => array(
      'arguments' => array('node' => NULL),
    ),
  );
}

/**
 * Create the HTML output for last created node
 *
 * @param $node
 * Node object for last created node
 */
function theme_YOURMODULE_node_last($node) {
  // Insert theming code here...
}

For more information on creating custom modules, see the Module developer's guide.


jdrupal entity_index success function not called I have an ionic 1 app with jdrupal. In a controller i query a remote api with this code:

// If logged in:
console.log('Hello ' + Drupal.user.name);

// Get the Contacts list.
var query = '';
var options = {
   'service': 'rest/basic',
   'resource': 'contact'
};

console.log('before entity_index');

entity_index('contact', query, options, {
   success: function (result) {
      console.log(result);
   }
});

the success function is never called. With Drupal.settings.debug = true; i can see the result is returned from the server. Status is 200, response contain my array of objects, but no success function call.

If someone has an idea?

thx,
david

According to its source code, success should be part of the options

options.success = function(result) {
    console.log(result);
}
entity_index('contact', query, options);


Create nodes from a JSON file uploaded in a form by an user I've got this form:

 $form['import_json'] = [
      '#type' => 'file',
      '#description' => $this->t('Allowed extensions: json'),
      '#title' => $this->t('Import your JSON\'s file.'),
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Import'),
    ];

I have to use '#type' => 'file' because AFAIK managed_file doesn't allow json file and file is the only type left.

I need to be able to get the uploaded file when the user submit the form to be able to convert the JSON's data to create nodes of a certain type.

My function is already created and it looks like this:

protected function createActualite(string $json)
  {

    $jsonstring = json_decode($json, TRUE);

    foreach ($jsonstring as $field) {
      $node = Node::create([
        'type' => 'import_content', // Machine name de notre content type 'actualité'
        'title' => $field['titre'],
        'body' => $field['body'],
      ]);
      $node->save();
    }
  }

The problem is that I can't find a way to properly get the uploaded file, I tried the same way that we do with managed_file

$file = File::load($field['import_json']);
        $file->setPermanent();
        $file->save();

but it doesn't work, also this (which is 10yo) doesn't do the trick either gist

If someone can lead me to arrive to save this file or to any doc, I would greatly appreciate.

Ok I made it works, first I get the file's path using the solution given here
and then once I got the path, I'm reading the file using
$file = file_get_contents($file_path);

then calling my function createActualite($file); and it creates all the nodes up to the content of the JSON as expected.


How do we know the required parameters of hook's callback method? I am working on creating a filter module starting with the hook_filter_info file. This hook requires a callback method via a 'process callback' filter setting.

Now the problem is: how do I know what parameters that this callback method requires? I have taken a look at filter.api.php and see this:

function hook_filter_FILTER_process($text, $filter, $format, $langcode, $cache, $cache_id)      {
$text = preg_replace('|\[codefilter_code\](.+?)\[/codefilter_code\]|se', "<pre>$1</pre>", $text);
return $text;
}

but I have seen this callback filter called like this :

mymodule_process($text, $filter, $format);

mymodule_process($text, $filter, $format, $language);

mymodule_process($text, $filter, $format, $language, $cache);

...

Now how do I know the amount of arguments that this method requires? Or does it require any argument at all?

I've never had to use this specific hook before, but I have found a breakdown of the callback in the Drupal docs:

https://api.drupal.org/api/drupal/modules!filter!filter.api.php/function/callback_filter_process/7

Pretty sure everything you're after will be described in the documentation. You can view all the other Filter API functions within the documentation here:

https://api.drupal.org/api/drupal/modules!filter!filter.api.php/7


How to add a node field to a database table in a custom module When I am writing my own custom module, and designing a database table, if I want to use the  field nid to refer to a node, because I want my module to adding something to each node, how should I implement this in the module's mymodule.install file?

Most of the time you will probably want to use the field API (CCK module in D6) rather than adding custom tables or modifying node by yourself.

Adding custom tables was a very D5 way of doing thing.

If you want to do this you will need to define your tables using hook_schema() and then in your mymodule_install() hook you can call drupal_install_schema() this should create a new table which represents your module.

It is worth mentioning that your schema should always represent your current schema. If you add a column you should alter the schema so that someone who installs your module will get the correct schema, but also write an update function to alter the table so that existing users get the correct new schema.

It is possible to alter other modules' tables, but I think that should be covered in another question.


Checkboxes not rendering All the other form elements render properly. Radios and Checkboxes do not. The title and descriptions show up, but not the boxes or radios.

$options7 = array();
foreach ($resqry1 as $option)
{
  $options7[$option->id] = $option->id;
}

$form = array();
$form['lis'] = array(
  '#type' => 'checkboxes',
  '#options' => $options7,
);

return $form;

Please help me out. Thanks

I faced similar situation while trying to inject checkboxes to user_register_form. I think checkboxes type is not valid type for typical rendering. Form elements of type checkboxes get totally reformatted within form_builder after form_alter hooks have executed. Make sure that form builder runs after you place your field.


How to implement "Add another item" for custom forms? I am writing a module which is basically a form that creates a relation between two end points.

I want a user to be able to create multiple relations at once. I want to add a button which says "add another item" just like how fields have when you select unlimited in their settings.

Is there a way I can do this to custom forms too ?

One way to do this is by setting the form fields/field sets within a for function. Create a seperate function to increment the value via a submit button callback for instance and rebuild the form after you increment.

for($x=1; $x<=$variabletoincrement; $x++){
(insert form fields/field sets )
}

Here is code from form_example_tutorial_9 which shows information on how to create dynamic fields. This information is much more thorough than my explanation:

http://api.drupal.org/api/examples/form_example!form_example_tutorial.inc/function/form_example_tutorial_9_add_name/7

http://api.drupal.org/api/examples/form_example%21form_example_tutorial.inc/function/form_example_tutorial_9/7


Use redirect after content creating and use $node I modified my submit handler to be redirected to a "thank you" page after creating some content. So far so good.

But I want to use some data of the node just created, so how can I transfer the $node-data of the just created node to my thank you page?

I created a new block to be shown only on the thank you page and I want to show some $node-data in my block...

function mymodule_block_view($delta = '') {
  switch ($delta) {
    case 'your_block':
      $block['subject'] = 'Share by mail';
      $block['content'] = mymodule_sharebutton();
      break;
  }

  return $block;
}

function mymodule_sharebutton() {
  $output = 'share';

  return $output;
}

I already tried with passing $node, $form, $form_state,... but with no luck.

Use arg(1); - (nid of the current node) in the hook_block_view and pass it in the link

function mymodule_block_view($delta = '') {
  switch ($delta) {
    case 'your_block':
      $nid = arg(1);
      $block['subject'] = 'Share by mail';
      $block['content'] = 'share?nid='.$nid.'';
      break;
  }
  return $block;
}

Once you do that, you can make your thank_you page react on the nid argument by loading the node:

$node = node_load($nid);

and extracting from it whatever you need


I want to create a new command for the nodes like the standard edit and delete In drupal you have the standard commands edit and delete which you access typing :

node/99/edit
node/99/delete

I want to create some other commands like :

node/99/approve
node/99/test
...

Where do I hook to access the command and execute some code ?

You need to use hook_menu() to define the path, coupled with the MENU_LOCAL_TASK type, e.g.

function MYMODULE_menu() {
  $items['node/%node/approve'] = array(
    'title' => 'Approve',
    'type' => MENU_LOCAL_TASK,
    'access arguments' => array('my custom args'),
    'page callback' => 'MYMODULE_approve_node_page',
    'page arguments' => array(1),
    'weight' => -1 // Controls the display order for the tab
  );

  return $items;
}

Then you just implement a callback function, which has the node passed as a parameter, and build up your page output:

function MYMODULE_approve_node_page($node) {
  // Do something with $node...
  $build = array(
    '#markup' => node_view($node, 'teaser')
  );

  return $build;
}

Once you clear Drupal's caches you should see the new tab appear alongside the View/Edit tabs on a node page, but only for those users who have the permission you define in your access arguments.


loading templates of region within page.tpl regardless of blocks being present I came to this query while trying to create my own theme. Say i have my region named footertop, which is placed above the footer. Its going to contain only some html content and some site logos which are static atleast for now.

I don't have any blocks to assign to this region but still want it to appear and had created a template file named block-footertop.tpl. But to my understanding (from drupal docs) this region only appears if any block is assigned to footer top region and is meant to be that way. My page.tpl.php doesn't have any conditions placed for this region, merely

<?php print $footertop; ?>

I'd like to know if there's any way to 'include' the template within page.tpl.php like its done with smarty. Most of the search i'd done showed me results containing *hook_theme()* and seemed different than what I'm trying to achieve.

Why I'm trying to this is to save a big bunch of html markup from being in my page.tpl.php and sheer curiosity to understand drupal theming better.

Any suggestions/solutions to this novice drupal enthusiast would be greatly appreciated.

Thanks in advance!!

First of all I think you should be sure you know the difference between regions and template variables. Second, there are different approaches to your question:

A) Custom region + block

You could indeed define a new region. This can be done in one of the two ways:

in your theme's .info file (best way) like this regions[regionname] = Region name
in the template.php file (haven't tried or felt the need to use this one)

After you defined your new region you can add blocks and content to it. You could just skip defining a new region and just add your block to the footer region or the region appropriate to your needs.

In your case your myTheme.info file would look something like this:

; $Id$
; @file: myTheme.info

regions[footertop] = Footer Top

output the region variable ($footertop)

/**
* @file page.tpl.php
* $footertop contains all the HTML content for that region
* and the blocks belonging to that region
*/
print $footertop;

.info file is cached in the database, so you need to clear the cache
add a new block: www.example.com/admin/build/block/add
add the block to the footertop region: www.example.com/admin/build/block/list/myTheme

When should you use this approach: when you have static content or/and just some snippets of text/html you want to add to your site. Remember to choose an appropriate input filter, otherwise some/all of your content might get filtered out.

Source: http://drupal.org/node/171224

B) Template variable

We want to define a new general variable available for all templates. Something like $content or $is_front. How do we do this: good old friend hook_theme :)

Create a new template file footertop.tpl.php and in it add the static data you want to add

/**
* Implementation of hook_theme()
* @file template.php - in your active theme
*/
function myTheme_theme(&$existing, $type, $theme, $path) {

  /*
  * If you are sub-theming another theme, like Zen,
  * you might need to do something like this
  * $hooks = zen_theme($existing, $type, $theme, $path);
  */

  $hooks['footertop'] = array(
    'template' => 'footertop',
    // 'arguments' => array(), // We could specify some arguments, useful when the content is not static
    // 'path' => $path . 'to/file' // This is also usefull if your template is in a subfolder
  );

  return $hooks;
}

/**
* Now we make our variable available to other templates
* file template.php - in your active theme
*/
function myTheme_preprocess_page (&$vars, $hook) {
  $vars['footertop'] = theme('footertop');
}

Now to add the variable in a template just do this:

/**
* @file e.g. page.tpl.php
*/

/* Some other code */

<?php print $footertop; ?>

/* Other code */

Source:

http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_theme/6
http://drupal.org/theme-guide/6-7

Now if you want to be a pro with drupal theming or development you should get yourself a book on this matter. It helped me a lot when I was struggling to understand how Drupal theming works :) You'll defined find the right one for you.


how do I make rounded borders around everything in a drupal 7 site? I have a site which is supposed to have rounded corners. what I need is a boarder that covers everything, but has rounded corners. right now, even with rounded corners, the boarders are square, and cover past the header. what am I doing wrong? I am using  border-radius 20px 20px 20px 20px; in the css

Not every browser has border-radius implemented yet. Use vendor prefixes for those.

.box_round {
     -moz-border-radius: 12px; /* FF1-3.6 */
  -webkit-border-radius: 12px; /* Saf3-4, iOS 1-3.2, Android <1.6 */
          border-radius: 12px; /* Opera 10.5, IE9, Saf5, Chrome, FF4, iOS 4, Android 2.1+ */

  /* useful if you don't want a bg color from leaking outside the border: */
  -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box;
}

Snippet from: http://css3please.com/


Find all the unused files In Drupal 7 (I also have the Media module installed), there is a functionality in
/admin/content/file

that lists all files being uploaded. If you click on a single file's "Usage" link, you can see exactly how many times that file has been used in the whole site, I would like to order that table by the column "Usage" to see files that haven't been used and then delete them.

Unfortunately it's not possible to order that column. Is there another way to achieve this? Is Views Bulk Operations the best available option?

It maybe isn't exactly what you are after but I found the answer at Find orphaned unused files and images to be most helpful.  Particularly the comment by @Marcos Buarque mentioning comment 7427898 which mentions a nice query to tidy up using the file_delete() function built into D7


Correct format of data to send at services endpoint to create node I have set up a services endpoint using services module and I am using Mozilla Poster add on to test it. I was able to create a user by sending data from Mozilla Poster in x-www-form-urlencoded format with parameter names "name", "pass" and "mail". Now I am trying to create a node but it is showing the error: "Title field is required".

What should be the parameter name for title field to be sent to the services endpoint? I tried using "title", "field_title" etc but it is not recognizing it. There is a nice tutorial here to determine data structure to be sent to create a node at remote website. But this tutorial tells how to send data in json format. I want to send data in x-www-form-urlencoded and create a simple node. The HTML code of title field of node create form at my remote website is:

<input class="text-full form-text required" id="edit-title-field-und-0-value" name="title_field[und][0][value]" value="" size="60" maxlength="255" type="text">

Kindly help me to figure out correct format to send title value in x-www-form-urlencoded format from Mozilla Poster in order to create a node.

In the html code of node add form as provided by you, title field has name "title_field[und][0][value]". You have to use exactly this name/key in your POST request. Along with that, you also need to send a value with name/key "title". Both needs to be sent. However the value of "title_field[und][0][value]" will be filled as title in the created node.


How to run drush tests from the command line? I installed drush via composer, initially drush 8 was installed.

I then try to run tests via drush test-run command,unfortunately I get the following output indicating the command is not found.

  (16:38 vagrant@devbox .composer) > drush test-run help The drush
  command 'test-run help' could not be found.  Run drush cache-clear
  drush to clear the       [error]

Installing version 7 via composer gives same output. Clearing the drush cache did not help, am I missing something?

The test-run command was removed from Drush; the recommendation now is to simply run the scripts/run-tests.sh script in Drupal folder directly.

See: Running tests through command-line.


How to use entity_metadata_wrapper for users particulary in hook_user_presave For node I can use the entity_metadata_wrapper like below

function mymodule_node_presave($node) {
  $ewrapper = entity_metadata_wrapper('node', $node);
  $ewrapper->title->set('new title');
}

However how can I use the entity_metadata_wrapper for users. I want to use entity_metadata_wrapper in hook_user_presave.

function mymodule_user_presave(&$edit, $account, $category) {
  ???
}

this variant works for me:

function mymodule_user_presave(&$edit, $account, $category) {
  $edit_object = (object) $edit;
  $ewrapper = entity_metadata_wrapper('user', $edit_object);
  $field_telefon = $ewrapper->field_telefon->value();
  $ewrapper->field_telefon->set($field_telefon.'123');
  $edit = (array)$edit_object;
}

Try casting $edit as an object:

function mymodule_user_presave(&$edit, $account, $category) {
  $ewrapper = entity_metadata_wrapper('user', (object) $edit);
}


Login without password I'm in a project where the main login form must not have a password field. The user will login with a username and selecting a Country. This country field is configured within the user profile.
So far, I can manage to log in users checking their username and the selected countries, but I can't find anything not to require a password for login.

This is my code.

function hdp_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login_block') {
    // Add country field to login form
    $form['pais'] = array(
      '#type' => 'select',
      '#title' => t('Pais'),
      '#options' => array(
        'Argentina' => t('Argentina'),
        'Chile' => t('Chile'),
        'Peru' => t('Peru'),
      ),
      '#required' => TRUE,
    );
    // Add validation to check country-username
    $form['#validate'][] = 'validacion';
  }
}

function validacion(&$form, &$form_state) {
  // Variables.
  $usuario_nombre = $form_state['values']['name'];
  $usuario_pais_seleccionado = $form_state['values']['pais'];

  // Search user countries by username. Username must not be duplicated.
  $uid = db_query("SELECT uid FROM {users} WHERE name IN ('$usuario_nombre')")->fetchField();
  if (!empty($uid)) {
    $paises = db_query("SELECT field_paises_value FROM {field_data_field_paises} WHERE entity_id IN ($uid)")->fetchAll();
    $paises_habilitados = NULL;
    foreach ($paises as $pais) {
    $paises_habilitados .= $pais->field_paises_value;
  }

  // Check if selected country is one of the user profile selected countries.
  $habilitado = strpos($paises_habilitados, $usuario_pais_seleccionado);
  if ($habilitado === false) {
    form_set_error('pais', 'Acceso denegado. Por favor revise su nombre de usuario y el país seleccionado.');
  }
}

If you don't require a password from your users, then you should:

Make the password form field not visible to the users (it is enough to set #access to FALSE)
Remove the form validation handlers that are not necessary

The form validation handlers that the user login block uses are the following:

user_login_name_validate() just checks the user account matching the username is not blocked
user_login_authenticate_validate() checks the entered password matches the one set for the user account using that username
user_login_final_validate() checks the user didn't enter too much times the wrong password

What you need to do is removing 'user_login_authenticate_validate' and 'user_login_final_validate' from the array $form['#validate'].

Remember also that your form validation handler needs to set $form_state['uid'], since that is the value used from user_login_submit() to load the user object from the database.

As additional notes:

Your code is making assumptions about where/how the field data are saved; in particular, it is assuming the field data are saved in the database currently used by the Drupal site, which is not necessary true, since field data could be saved in MongoDB. I would rather use the following code.

$uid = db_query("SELECT uid FROM {users} WHERE name = :account_name", array(':account_name' => $usuario_nombre))->fetchField();
if (!empty($uid)) {
  $account = user_load($uid);
  if ($countries = field_get_items('user', $account, 'field_paises')) {
    // I assume users can just select a single country.
    $country = array_shift($countries);
    if ($country != $usuario_pais_seleccionado) {
      // Show the error message.
    }
  }
}

You cannot use user_authenticate(), since that requires the account password, which is not saved in the database. The database contains the password hash.
The string passed to t() should contain words in English, since the function is used to translate from English to the language currently set for the site. (Pais is not an English word; probably you meant Country.)
Instead of WHERE name IN ('$usuario_nombre'), you should use WHERE name = :username. Input from users should not be used directly in SQL queries, as that is a security issue. (See SQL injection.)
Functions implemented by a module should always have their names prefixed by the module name.

Talking of security issues, I hope you are using the authentication method you described in a very restricted, controlled environment. I would not use it in a public site where everybody can create an account, especially if the username and the country selected from users are visible to everybody. Even in the case the country is not visible, getting the right username/country combination is much easier than finding the right username/password combination that allows you to log in.


Select all checkboxes of an entity reference field on creating a node Drupal 8.7.x

For one of my content types I have an entity reference field referencing a taxonomy vocabulary. I have a lot of terms in this vocabulary which makes it tedious to check all the checkboxes if you practically need all of them checked. I would like to integrate a single checkbox at the top of the field in the node creation form that allows you to check/uncheck all the terms at once.

I found a few modules that do this in drupal 7 but so far I had no luck finding anything related to drupal 8.

How would I go about integrating this functionality myself ?

At the moment I have a jquery function in my theme that adds a checkbox at the top of the fields like so:

(function ($, Drupal) {

  /**
   * Check all checkboxes.
   */
  Drupal.behaviors.initFootnotes = {

    attach: function (context, settings) {

      $(".form-checkboxes").prepend($('<input type="checkbox" class="form-checkbox shield-select-all" /><label class="option shield-select-all-label"> Select / Deselect all </label>'));

      let selector = $(".shield-select-all");
      selector.on('click', function (event) {

        console.log("the checkbox is clicked");
        let $options = $('.form-type-checkbox');

        $(".form-checkboxes").closest().find($options).each(
        console.log("I'm an option"),

        $(this).find("input[type=checkbox]").click(),

        )
      })
    }
  };
})(jQuery, Drupal);

The select all checkbox is added but the checkboxes aren't changing their state when the select all checkbox is checked. I noly get "I'm an option" once in the console.

Thanks in advance,
Geordi

Ended up resolving this issue with the following code:

(function ($, Drupal) {

  /**
   * Check/Uncheck all checkboxes.
   */
  Drupal.behaviors.selectAll = {
    attach: function (context, settings) {
      $(".form-checkboxes").prepend($('<input type="checkbox" class="form-checkbox shield-select-all"/><label class="option shield-select-all-label"> Select / Deselect all </label>'));
      $(".shield-select-all").on('click', function () {
        let $isChecked = (!$(this).attr('checked'));
        $(this).parent().find('.form-type-checkbox input[type=checkbox]').attr('checked', $isChecked);
        $(this).attr('checked', $isChecked)
      })
    }
  };

})(jQuery, Drupal);


Assign all permissions to a user programatically Is there a way to assign all the permissions to an authenticated user through code, I want to do it in unit tests.

You could use rules - when a user is created (could include certain contextual requirements) then all the roles are added.

or the less tidy way

You could get all the roles from the DB and then insert each into the user_roles table.

Something like:

$userID = 'ENTER UID';
$query = db_select('user_roles', 'r')->fields('r')->execute();

while($role = $query->fetchObject()){
    db_insert('user_roles')->fields(array('uid' => $userID, 'rid' => $role->rid))->execute();
}
drupal_static_reset('user_access');  /* Flush the caches */
drupal_static_reset('user_role_permissions');  /* Flush the caches */

The code is untested but should be a good foundation.

You can also do the same in Drupal by loading the user object and making the changes, but the above will do the same.


How to allow multiple values in a single value textfield I am using views_conditional module for Drupal 7 and would like to use a comma separated array (i think this is called an array?) of values in the "This value" textfield.
For example, I would like to add a views conditional field that checks for:
If this field...
[type] == Content Type
Is...
Contains
This value...
Apples, (or) Oranges, (or) Bananas
As it is right now, (unless I am missing something) I would need to add 3 separate conditional field. One for each content type (apples, oranges, and bananas) though they are all executing the same function.
(I think) The current definition for the value field is:
$form['equalto'] = array(
  '#type' => 'textfield',
  '#title' => t('This value'),
  '#description' => t('Input a value to compare the field against.  Replacement variables may be used'),
  '#default_value' => $this->options['equalto'],
);

I also think the logic for the "Is..." operator in this use case would technically need to be something like "Contains Any".
(I think) The "Contains" function is defined here:
      // Contains
  case 7:
    if (mb_stripos($r, $equalto) !== FALSE) {
      return $then;
    }
    else {
      return $or;
    }
    break;

Is there a way to simply write a couple of hooks to alter the form, or would i need a full blown module patch?
Any help or pointers would be greatly appreciated! I am pretty new to backend code. I also posted a support request at Drupal.org

There is a patch for this for anyone else looking for a solution.
https://www.drupal.org/project/views_conditional/issues/2690167


Conditionally display a field based on another field's content by field.tpl.php What i would like to achieve is to be able to show the field's content only if another field of the node being displayed has a certain value. So I'd like to put an if condition at the beginning of the custom field.tpl.php that controls whether the content is public or restricted based on another field's value (whether the node is tagged as free or not).

Actually, what I am trying to achieve is  to make a double control: if the node is tagged FREE, display it right away, if not, see the user's permissions and display it of he has "paid user" role (just to explain things).

I don't think that you need a custom field.tpl.php or custom module. You can just copy the field.tpl.php from a field module and modify it. Look at comments above the field.tpl.php:

$items: An array of field values. Use render() to output them.
...
$element['#object']
$element['#field_name']
you can get user info from global $user object;

i think these are key variables which you can use.
E.g. (poorly modified version of field.tpl.php. But logic is like this):

<?php
  global $user;
?>

<div class="<?php print $classes; ?>"<?php print $attributes; ?>>
  <?php if (!$label_hidden): ?>
    <div class="field-label"<?php print $title_attributes; ?>><?php print $label ?>:&nbsp;

  <?php endif; ?>
  <div class="field-items"<?php print $content_attributes; ?>>
    <?php foreach ($items as $delta => $item): ?>

      <?php
        if($element['#field_name'] == 'field_NAME') {
          if($item == 'MY_VALUE (e.g. free)') {
            $output = render($item);
          }
          elseif($item != 'MY_VALUE (e.g. free)' && isset($user->roles[MY_ROLE_KEY]) {
            $output = render($item);
          }
          else {
            $output = ''; // or whatever you want
          }
        }
      else {
        $output = render($item);
      }
      ?>

      <div class="field-item <?php print $delta % 2 ? 'odd' : 'even'; ?>"<?php print $item_attributes[$delta]; ?>><?php print $output; ?>

    <?php endforeach; ?>

//P.S. Putting your logic into .tpl is not good..


Change shown fields in a grouped view depending on group I have a view that shows nodes and groups them by their taxonomy term. Is it possible to show less fields for a specific term? For example there are user profiles with names and pictures that are listed, but if they have a specific taxonomy term the picture field shall not be shown.

These types of problems are often solved by creating another Views display.

Add a Filter to your original Views to only show the results with the terms where you want to show the additional fields.
Then Duplicate this display as Attachment, attach it to the original views display.
Override the Attachment Filters and change the one for the terms - reverse the choices to filter out only the terms where you don't want additional fields
Override the Attachment Fields, remove the ones you don't want.

The Attachment results will display below or above the original results, depending on whether you choose to attach it After or Before.


PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1532856' for key 'PRIMARY': INSERT INTO {watchdog} I am worried about a big error found on my website.Yesterday it was working and today morning i found the issue.Please help me to solve it.

Error message:

  PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062
  Duplicate entry '1532856' for key 'PRIMARY': INSERT INTO {watchdog}
  (uid, type, message, variables, severity, link, location, referer,
  hostname, timestamp) 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); Array ( [:db_insert_placeholder_0] => 0
  [:db_insert_placeholder_1] => php [:db_insert_placeholder_2] => %type:
  !message in %function (line %line of %file).
  [:db_insert_placeholder_3] =>
  a:6:{s:5:"%type";s:6:"Notice";s:8:"!message";s:46:"Undefined index:
  field_enter_module_name_here";s:9:"%function";s:9:"include()";s:5:"%file";s:112:" example.com\sites\all\themes\nexus\templates\field-collection-item.tpl.php";s:5:"%line";i:37;s:14:"severity_level";i:5;} [:db_insert_placeholder_4] => 5 [:db_insert_placeholder_5] =>
  [:db_insert_placeholder_6] => http://example.com/
  [:db_insert_placeholder_7] => [:db_insert_placeholder_8] =>
  195.229.241.186 [:db_insert_placeholder_9] => 1432102144 ) in dblog_watchdog() (line 160 of
  example.com\modules\dblog\dblog.module).

There are 2 things going on here.

The PDOException is because Watchdog is trying to insert a duplicate primary key, 1532856. Your auto increment value could be off or some other table corruption could be going on there. A simple fix is to truncate the watchdog table if you don't care about maintaining old log data. Otherwise, you could try to repair the table or fix the auto increment value if you want to retain old log data.
The error being logged has to do with your field-collection-item.tpl.php template in the Nexus theme on line 37. A key called field_enter_module_name_here is being referenced when it doesn't exist. It looks to be a custom template addition to the theme (it doesn't exist in the 7.x-1.3 release). Given, the key name, it sounds like some sort test code dropped into this template. This is warning so it shouldn't be a critical problem, but you should fix it to clean out extraneous errors from filling up your logs.


How do I set a content entity field as required? How do I make a field in a content entity required in Drupal 8?
I tried FieldConfigInterface::setRequired(), but it doesn't seem to work.

You need to use the ->setRequired(TRUE) option on the field. IE

$fields['source_id'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Thingy'))
      ->setDescription(t('Pick a thingy'))
      ->setSetting('target_type','thingy')
      ->setRequired(TRUE)
      ->setDisplayOptions('form', array(
        'type' => 'options_select',
        'weight' => 5,
      ))
      ->setDisplayConfigurable('form', TRUE);

You will also need to uninstall and then reinstall your module to have the change reflected in the database before this will work.


Migrate row data into text formatted long multiple I would like to import 3 different row values into a multiple text formatted long field.

This is my migrate (plus) map yml:

  ...
  field_mytext_formmated:
    plugin: get
    source:
    - dataValueA
    - dataValueB
    - dataValueC
  ...

The data is being migrated but the main problem is that the format property is not being filled so the HTML content is not interpreted.
I don't figure out how to set the format to full_html for all fields.

I've seen that for just one field I should use something like:

'body/value': example_matched_field

https://www.drupal.org/docs/8/api/migrate-api/migrate-process-plugins/migrate-process-overview

But it doesn't seem to work with multiple values.

Thanks!

There is a plugin named iterator which allows iterate a list of associative fields to a compound field.
Example:
field_formatted:
      plugin: iterator
      source:
        - fieldA
        - fieldB
      process:
        value: value
        format:
          plugin: default_value
          default_value: 'full_html'

In this case the fields should have this structure
    [
      'fieldA' => [
         'value' => 'Chicken',
      ],
    ]

Can you fields you adapt your source fields to use iterator plugin in this way?


Image Resize Filter not working with WYSIWYG + CKeditor? I have installed image resize filter, set it to be active on the 'full editor' content editing mode which is where I have CKEditor activated.  CKEditor is working great, the problem is that I don't see any image resizing functionality.

I have insert installed as well. I can upload a file, and when I hit insert it goes into the CKeditor as the original size.

I added an images field to Basic Page which got the upload button/insert showing up and that's working great, but I see no sign of Image Resize Filter in action anywhere :?

For re-sizing of images instead of using Image Resize filter you colud use the feature of drupal 7 itself ie by setting up an File Type for your image.

You could set up a File type you should go to Configuration -> Media -> File types -> Manage Display

There are basically 6 types of image file type that you could use

Link
Default
Preview
Large
Original
Small

These are the default file type that you can select and are there with there default values so we could override the default values by our own values and could use that file type for uploading our own images of particular size.


Does the language filter show all languages by default? I'm looking at a Drupal 6 site with the following modules installed, all of which I think are contributing to translation:

Internationalization
Locale
Content Translation

As I am not experienced with site translation I'm not sure which module is contributing to this, but the "Language Switcher" block shows both English and French for all content, regardless of the language choice assigned in the node, or if there are any translations present.

It is claimed that previously, if there was only an English translation for the node, then only English would be available from the language switcher block. However, if I add a new node, with just an English translation, I can still select French, which, because there is no translated node, takes the user to the internal node path, e.g. instead of:

/en/mycontent/foo

it would be

/fr/node/232

which of course, breaks contexts and what-not.

So what module does the language switcher block get provided by in this case and should it always show both languages?

"Switch Language" block created by "Locale" module which is the most fundamental  language handler in drupal. Its purpose it to switch user interface between languages. If translation exists for certain node it will used if not, only interface changes.

"Content Translation" module handles relations and links between translated nodes. The link you need is something like the language link/s that, by default, displayed inside node's links area.

I am not aware of existing  module that display these node links in block.
But you can display this list using code.

First, get can get an array needed links using translation_link() that supplied by "Content Translation" module

$node_translations = translation_link('node', $node_object);

Than, create HTML list out of that array, using theme_links(),

print theme('links', $node_translations, $attributes = array('class' => 'links langs more-classes-if-you-wish'));

To display this in block you can create new custom block with php input format or create template file for that block and make your code live there.
To get node object in block you can use

  if (arg(0) == 'node' && is_numeric(arg(1))) {
   $node_object = node_load(arg(1));
  }


What is the best way to add "last_imported" field into a view for a node entity-reference field joined to migrate_map table? I have a node which has an entity-reference field. The enitity in that field is being imported via Migration framework.
So if I call that entity fruit. MyNode has a field call fruit. Which is being migrated from an up-stream. Thus, it has a "migrate_map" table call "migrate_map_fruit".
In which it has a column call "sourceid" which can be joined to "fruit.id" and then I want to extract a field call "last_imported" and display in the view.
What would be the best way to bring it to views ?
It's quite complex so feel free to reach me if you need more clarification.

So I found the solution to that.
You have to add relationship to referenced "fruit" entity to the view. And immediately following field will be available.
In my fruits_import.module.php I added hook_view_data() as follows.
/**
 * Implements hook_views_data().
 */
function fruits_import_views_data() {
  $views_data = [];
  // Exposing Migrate Map table.
  $views_data['migrate_map_fruit']['table'] = [
    'title' => t('Related migration'),
    'group' => t('Fruit Entity Migration Tables.'),
    // Watch out! This is not a base table, so we use a different key and
    // explain to Views how this table can be JOINed to our base table of
    // 'fruit'.
    'join'  => [
      // We are explaining Views how 'migrate_map_fruit' can be JOINed to 'fruit'.
      // By the way, you do not necessarily have to JOIN onto a base table. You
      // may as well JOIN in chain a few non-base tables. Although for a table
      // to become visible in Views UI, it must be connected one way or another
      // to a base table on which the view is being built.
      'fruit' => [
        // Column from 'fruit' table which will participate in the JOIN clause.
        'left_field' => 'id',
        // Column from 'migrate_map_fruit' table that will participate in the JOIN
        // clause.
        'field'      => 'destid1',
      ],
    ],
  ];
  // Exposing last imported col only for now. (We could expose other ones here)
  $views_data['migrate_map_fruit']['last_imported'] = [
    // Human friendly name for Views UI.
    'title' => t('Last Imported'),
    'help' => t('Timestamp for an fruit last imported.'),
    'field' => [
      // In the 'id' key we place the name of Views field plugin that is
      // responsible for operating the column. The id "date"
      // corresponds to \Drupal\views\Plugin\views\field\Date class. It is
      // an extremely simplistic straightforward field plugin that appends the
      // column into SELECT query (see ::query() method) and then displays the
      // fetched column as field output (see ::render() method).
      'id' => 'date',
    ],
  ];
  return $views_data;
}

Credits to awesome Views tutorial by Oleksandr


Module getting "$entity" argument error with hook_entity_presave() I am trying to create a module in Drupal 8 (8.9.11) and this module uses the function hook_entity_presave in order to update a node / entity programmatically. I've tried the answers from hook_entity_presave() doesn't work, I was able to add those in my code.
sno.routing.yml
sno.content:
  path: /node/add/issuances
  defaults:
    _controller: Drupal\sno\Controller\SnoController::sno_entity_presave
  requirements:
    _permission: 'access content'

src/Controller/SnoController.php
namespace Drupal\sno\Controller;
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeInterface;
class SnoController {

  public function sno_entity_presave(\Drupal\Core\Entity\EntityInterface $entity) {
    if ($entity->getEntityType()->id() == 'issuances') {
      $entity->set('field_s', ', s. ');
    }
  }

}

When I got into adding a content of content type issuance (/node/add/issuances), I am getting the following error.

The website encountered an unexpected error. Please try again later.
RuntimeException: Controller "Drupal\sno\Controller\SnoController::sno_entity_presave()" requires that you provide a value for the "$entity" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one. in Symfony\Component\HttpKernel\Controller\ArgumentResolver->getArguments() (line 78 of /var/www/senate-library/vendor/symfony/http-kernel/Controller/ArgumentResolver.php).

The exception you get (Controller "Drupal\sno\Controller\SnoController::sno_entity_presave()" requires that you provide a value for the "$entity" argument) is caused from the fact the controller's method associated to the sno.content route you define doesn't get any $entity argument, which is instead listed as its parameters.
That is a route, anyway, not a hook. If you want to implement hook_entity_presave(), you don't need to define a route for that. If the module isn't defining other routes, the sno.routing,yml file isn't even necessary.
As Jaypan already said, hooks aren't methods implemented in a class. They are plain PHP functions with a specific name.
In your case, it should be the following function. I corrected the function code because:

In a path like /node/add/issuances, issuances is the content type, or node bundle, not the entity type. As the code should act on a node whose bundle is issuances, the code needs to check the value returned from $entity->bundle().
Since hook_entity_presave() is invoked for every entity Drupal saves, it's necessary to check which entity is being saved, by checking the value returned from $entity->getEntityTypeId(), not just its bundle. This handles the case where two different entities have a bundle with the same name.

I took the module machine name from the namespace used in the question code and from the name of the routing file. If those are correct, also the module machine name should be correct.
// Put the following line on the top of the sno.module file.
use \Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_entity_presave().
 */
function sno_entity_presave(EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'issuances') {
     $entity->set('field_s', '<value to assign to the field>');
  }
}

Alternatively, if the module only has code for a single entity type, hook_ENTITY_TYPE_presave() can be instead used. In this case, it's not necessary to check the entity type, as the hook is only invoked for a single entity type. (In this case, the entity type is Node.)
// Put the following line on the top of the sno.module file.
use \Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function sno_node_presave(EntityInterface $entity) {
  if ($entity->bundle() == 'issuances') {
     $entity->set('field_s', '<value to assign to the field>');
  }
}

As for the field, it's usually field_s for a field added via UI. If it's defined from code, the field is simply s. You need to verify the correct way to reference that field, as that isn't clear from the code shown in the code.
As side note, if you edit the code of a module that is installed, you need to install or uninstall a module, to make Drupal notice you added a hook into that installed module, as Drupal caches the list of hooks implemented by modules, and clears it when a module is installed or uninstalled.


Drupal 7.x Development - Naming conventions Because of a recent project I need to dig into this drupal thing and try to fix a bug inside.

I am a drupal CMS beginner,and studying this CMS for several days, also going through the drupal module development website.

But I still have no clue about how to do proper development in Drupal, especially the function naming, database table naming, and relationship between .module, .info and so on.

e.g. hook_revision_publish become revisioning_revision_publish

My question:

How are names mapped and what is the sequence of functions that are called (the workflow?)

Hope that my question is clear and help someone to shorten the learning path of Drupal.

Thank you very much in advance for helping.

I'm a bit surprised that you haven't found anything on the internet that could answer your questions. Here is an article about coding standards for Drupal.

Anyway, here are several things I always do with naming, functions and directories (that doesn't mean it's the best conventions):

The only directory you should work in is ./sites (please never ever edit something in the other directories).
The contribute modules you download should be placed in ./sites/all/modules/contrib
The custom modules that you develop yourself should be placed in ./sites/all/modules/custom
When you create a custom module, chose a simple and suitable name of it, preceded by the name of your project (better), for example myproject_blog.
The .module and .info files should have the same name as your module's, for example myproject_blog.module and myproject_blog.info. It will automatically make the relationship between them.
All the functions that appear in your .module file should be named by your module's name, for example myproject_blog_revision_publish().
If your custom module needs a table in your database, the name of your module has to show up somewhere, for example $schema['myproject_blog']. If you need more than one table, keep the prefix and add some explicit suffix.
Idem for the custom themes in ./sites/all/themes.

If I forgot something, just ask ;)


How to add an editable text box to a page So i have created a page which uses an XML feed to generate some output. I want to be able to add a textarea from the FORM API so that i can allow user of my site to enter some details on to the form itself.

Similar functionality to how entityform works, seemed like a simple task, but not sure how to do it.

OK thought i would answer my own question and show the method in which this is done. First declare a block, with a block view and then define a custom callback function that defines the textarea, are any output from Drupal's Form API.

function hook_block_info() {
  $blocks['box_question'] = array(
    'info' => t('Box question area'),
  );
  return $blocks;
}

function hook_block_view($delta = '') {
  $block['subject'] = t('TEST');
  $block['content'] .= drupal_render(drupal_get_form('custom_block_form'));
  return $block;
}

function custom_block_form($form, &$form_state) {
  $form['question'] = array(
    '#markup' => 'this is a block,
  );
  $form['answer'] = array(
    '#type' => 'textarea',
    '#resizable' => FALSE,
    '#default_value' => $default,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#name' => 'save',
    '#attributes' => array(
      'class' => array('save-button'),
    ),
  );
  return $form;
}

The custom_block_form is what defines the form blocks, call the submit functions to make your own callback on what to do when the form is saved.


/sites/default/files images not showing up This is for a Drupal 6 site, but I've seen this problem with Drupal 7 before too.

I migrated my site from a main domain (www.domain.org, let's say), to a development domain, with a subdirectory, (www.devlin.domain2.com/domainupgrade).

That breaks the images located in /sites/default/files, but not the files located in /sites/all/themes/themename

How can I fix this? I've tried changing file permissions (shot in the dark) as well as the base url setting (but I perhaps didn't change it to the correct value?)

How can I get images to show up in this context on the development site?

I appreciate that this is an old post but after days of trying to resolve the problem I have seen many of these posts and want to update with my solution.

My web host is classed as a shared web host which means for me that I don't have as much access to the server side as with other hosts. The control area for the admin on my host is custom and lots of stuff that I have with another host and previous hosts id missing.

I resolved the images not showing by adjusting the .htaccess file. There are 2 that I have found so far in Drupal 7.24 (one in the site root and one in sites/default/files/) and I had to adjust both of them by commenting out the options section and the symlinks section. There is info on this by googling "one.com Drupal Installation".

Once both htaccess files had been edited and the permissions had been changed on the "files" folder in "sites/default/" to "755" the extra folders where created when I uploaded my images and the images started to show fine. If like me you are unable to change permissions within your website hosts control panel you will need to do it with either an ftp client or via ssh.


Does anyone know solution for adding pure javascript filter for View? As in queston. I was googling and searching forum, but found nothing useful.

I want to setup dynamic filter for a view. Eg. http://silverwareconsulting.com/index.cfm/2008/10/2/jquery-autofiltering-table. One difference is that I need to take filter value from textfield.

Maybe this functionality is built-in in Views, but I missed that?

I'ld suggest you choose views format Table and then add your JS from hook_page_build().


Automatically fill the default vocabulary term associated with a content type when editing a node What I'm trying to do is to automatically select the default term in the "add content" page based on the user's location in the site.

Example:
User is currently viewing classifieds listed under "Los Angeles", which is in "California", which is in the "Locations" vocabulary.
I want to automatically set the default value of the "Locations" vocabulary shown in the the content form for new classifieds to the term that identifies the area they are viewing.

Is this possible?

NOTE: I'm not referring to GeoIP or locations-based modules. I'm just looking for a way to automatically select the term they are already viewing, and use it for the node being created.

I think the answer will be to make your button/menu item dynamic using arguments from the URL. It sounds like when a user clicks the "Add Classified" they are already viewing the classifieds tagged with a particular location taxonomy term. In which case, I'd imagine that term name (or id) appears in the current url, something like http://yoursite.com/classifieds/LosAngeles. If so, I believe you can pull that term out of the url and use it in your link, something like http://yoursite.com/node/add/classified/LosAngeles. Then, you'd need to alter your 'Add Content' form to pull in the term from the url (the LosAngeles part). This should work in theory, however I'm not sure exactly how to do that in practice. I'll see if I can figure it out before you end up answering your own question, but that should at least help point you in the right direction for now.


Merge multiple block views to a single jump menu I want to implement a jump menu with a list of three different vocabulary terms grouped by each vocabulary name. If I make only a single view all the terms are shown correctly but I would like to be grouped by their vocabulary names. I thought that I could have this result if I could merge three different views with a view for each vocabulary.

Is this possible?

Well... It was very simple. I just used a single block view with all the vocabularies and I just used "Group by" the field vocabulary name. This outputs the option values within optgroups for each vocabulary.


Programmically add multiple empty fields on a multiple value field/form In Drupal 7,  When you set a field "Number of values" to unlimited, it will show you 1 field on the creation page with an add more button.  How would one go about so it shows 5 empty fields on the creation page?

Have tested this in Drupal 8 but I think it is the same for drupal 7.

if($form_id == 'node_MYCONTENTTYPE_form') {
  $item = $form['FIELD_MY_FIELD_NAME']['widget'][0];
  for ($n=1; $n<5; $n++) {
    if(!isset($form['FIELD_MY_FIELD_NAME']['widget'][$n])) {
      $form['FIELD_MY_FIELD_NAME']['widget'][$n] = $item;
    }
  }
}


How can i prevent field display on sign up while using profile 2 module In my site, I used the profile 2 module to add some fields to the registration/sign up page.
Is there a way to exclude some of these newly added fields from being displayed at sign up, so that a new user will only see them when he wants to edit his/her profile ?

Thank you.

If you go to admin/structure/profiles and click on Edit for the desired profile type, you can configure these settings.

Simply uncheck Show during user account registration. You can even eliminate the profile from the account page by checking Provide a separate page for editing profiles. .

If you want to restrict access to particular fields only, use the Field Permissions module and set the View permissions on the selected fields to Authenticated user. On registration the user is still Anonymous, and will not be able to see the fields.


Passing variables to JS from theme folder .tpl files I use many template files in my modules via hook theme. In order to pass variable to JS files I use the method described here:
https://www.drupal.org/node/304258
in the .tpl.php files:

$my_settings = array(
  'basePath' => $base_path,
  'animationEffect' => variable_get('effect', 'none')
);

drupal_add_js(array('myModule' => $my_settings), 'setting');

and then in the .js files:

var basePath = Drupal.settings.myModule.basePath;
var effect = Drupal.settings.myModule.animationEffect;

For the first time (it seems) I'm trying to pass variables to JS from .tpl files located in my theme folder.
Suppose I have a content type called 'cars',  I craete a page-cars.tpl.php template file in my theme folder which automatically applies to all car pages. But in these tpl files I can't pass variables to JS using the method described above.
I tried switching 'myModule' to 'myTheme' but Drupal won't recognize it as a defined setting

As per Clive's instructions I added to the my_theme_preprocess_content_type(&$variables) function and it works! (thanks Clive)

Take a look at the variable_set function. If my memory is correct, I used this to move variables between PHP and java script.


How can I allow HTML links in translated strings? I created a custom D8 module with all text strings declared in English, either via this->t(), t() or in various configuration (YML) files.

I am now in the process of translating those strings in French so that I can then extract them and package them with the module.

My issue: some strings for the interface contain HTML links (mostly refering to other Drupal admin pages); they display and work fine in English, but when I try to translate those strings via the Drupal UI, I get an error saying "The submitted string contains disallowed HTML". If I remove the  then the error disappears.

Here's an example of a string containing several links:

$this->t('
Some explanations here. You can find a more information
  on the help page.
Note: after changing this value,
  you may have to clear the cache for this setting
  to take effect.
', array(
  '@hhelp' => '../../help/mymodule',
  '@hperformance' => '../development/performance',
)),

Is it possible to translate those strings while keeping the links in the translation? How should I proceed?

the problem is the absence of the quotes. I try to insert this traslation on a drupal site and it work!

Some explanations here. You can find a more information
 on the help page.
Note: after changing this
  value,you may have to clear the cache
  for this setting to take effect.

It also work with "


Custom Drupal admin theme per role Under the "menu" > "settings" navigation tabs there is the option to set primary and secondary links.

Is this strictly for backend or front end?
Can I use these settings for a backend, if so, how get_variables()?
I want to be able to configure custom menus based on roles, I will implement a module to support this but any tips or pointers (API of interest) is greatly appreciated.

Thanks,
Alex

Regarding "Menu > Settings" , You can able to select

Source for the Main Links (Primary menu)

  Select what should be displayed as the Main links (typically at the
  top of the page).

Secondary links

  Select the source menu for the Secondary links.

For example, If you created a new menu called Header Menu and added some links, now you would like to display Header Menu as Main Menu on top of page which is nothing but Primary Links. In that case you have to set "Source for the main links to " Header Menu.

Reading these values

Yes, You can able to read these values using below code

$primary_menu = variable_get('menu_main_links_source', 'main-menu')
$secondary_menu = variable_get('menu_secondary_links_source', 'user-menu'),

Regarding menus based on roles

You can try using Menu Item Visibility Module

  This module exposes configurable and extendable visibility settings
  for menu links. For example, if you want to create a 'My account' link
  that points to /user, both anonymous and registered users have access
  to the /user path, so both will see the link, even if anonymous users
  do not technically have an account.


Auto-upload image feature with image browser module (e.g: Image picker) I am using the imagepicker module for browsing the uploaded images, I have tried searching for the auto-upload integration for this module but still no luck.

I am searching for any alternative way if there for similar thing (mainly I require image browser to use the already uploaded images, and implementing the auto-upload functionality on it).

Any suggestion/recommendation would be appreciated.

Not sure it would help, because I don't know what you mean by "auto" uplaod, but here is the configuration I use:

FileField Sources module
https://drupal.org/project/filefield_sources

with IMCE module:
https://drupal.org/project/imce

FileField source is pretty usefull to present user a set of upload options for a single image field.


Incorporate dropdown list of nodes into a webform to link webform results to said content I am trying to link the results from a webform comment survey to content that was previously generated within a site so that the webform_submissions table in the database shows the node those answers are attached to.

I am planning to use a "node reference" dropdown to the content type I need, but that's as far as I've gone.

Any ideas or suggestions are most appreciated.

You can create your own predefined lists by using the webform_webform_select_options_info() hook.

<?php
/**
* Implements hook_webform_select_options_info().
*/
function yourmodule_webform_select_options_info() {
  $items = array();
  $items['contentchoice'] = array(
    'title' => t('Content Choice'),
    'options callback' => 'webform_options_yournodes',
  );
  return $items;
}

Then generate your list of nodes using

/**
* Webform options info callback.
*/
function webform_options_yournodes() {
  $mynodes = array(
  //build your array up here
  );
  return $mynodes;
}


Passing arguments to a URL with view blocks and contextual filters I have a page that displays nodes of awards. These awards have taxonomy Year added to them. The url to them is : url.com/aboutus/awards.  I have a block view created that pulls the awards and I've set a contextual filter that filters the awards by year.

When I type in a URL such as url.com/aboutus/awards/2013, I want only the 2013 awards to be listed.  I've been trying to accomplish this with a dynamic field but the argument isn't passing.

Does anyone have any idea how I can solve this? (I am a newbie to Drupal, so apologies if my vocabulary isn't completely accurate.)

Views comes with a (initially disabled) page that will display your taxonomy terms for you. If you look for "Taxonomy Term" in your views overview you should find it. It will display all of your taxonomy terms through a view.

It is recommended that you enable the view, clone it, disable the original and work with the clone, to begin with. However, be careful as it will turn all your taxonomy terms into a views page.


Moving site from one environment to another I have a Drupal 8 site installed on a staging server. When moving on the production server,  I do a git pull, import the database and the site is there and working. I do the same after some configuration is changed,I do a git pull and the usual drush cim, but I get:

  Cannot change the install profile from to standard once Drupal is installed.

How do I get around this?

Check your settings.local.php (or settings.php if you don't have one) for 'install_profile' and make sure this is set and matches your staging environment:

https://github.com/drupal/drupal/blob/2e8b29651cfb08309098c239ce9d03e724d747b3/sites/default/default.settings.php#L279

If that doesn't work you can take a look at https://www.drupal.org/node/2870028 as @jaypan said


Customising field container I've created a cck field formatter. The field outputs uploads from filefield into embedded iframes that link to google docs for display. It currently outputs:

Download the document

Download the document

I would like to edit the html outside the contents of the .field-item. Is it possible to do this in the module or do I have to create a custom theme tpl for it?

I'm often using the excellent module Custom Formatters for this kind of purpose. Simple and clean.


How to add a new webform submission formatter for the webform components I'm just wondering how to add a new option to the webform submission formatters for a specific element? is it driven by the field API?

What you have in that list are date formats. You can manage those, including adding new ones, at /admin/config/regional/date-time.


How to create a new field collection+fields in a programmatically added content type I'm very new to creating modules and I'm creating a content type for the first time programmatically.

Creating the content type works fine, I've even added some fields. But now I'd like to create a new field in that content type which is a field collection.

I can't find a good spot on the internet that explains how I can add a new field collection to a new content type. All programmatically in one run.

Can anyone help me out how to achieve this?

It involves this contributed module.

I googled _create field_collection programmatically_ and this example was from my first search result.

  Thought I would post my solution for programmatically creating a field collection, along with an attached field, during a module install. The example is specific to my use, but easily modified to add the field types you need. Of course, if there is an easier way please feel free to add your thoughts. This works with the current 7.x-1.x-dev branch.

/**
 * Create a Field Collection field and attach collection node reference
 */
function _create_field_collection() {
  $t = get_t();

  $fields_array = array(
    array(
      'field' => array(
        'field_name' => 'bir_collection',
        'label' => $t('BIR Collection Nodes'),
        'cardinality' => -1,
        'type' => 'field_collection',
      ),
      'instance' => array(
        'field_name' => 'bir_collection',
        'entity_type' => 'node',
        'bundle' => 'article',
        'label' => $t('BIR Collection Nodes'),
        'description' => '',
        'widget' => array('type' => 'field_collection_embed'),
        'required' => 1,
      ),
    ),
    array(
      'field' => array(
        'field_name' => 'bir_collection_node',
        'type' => 'node_reference',
        'label' => '',
        'cardinality' => 1,
        'settings' => array(
          'referenceable_types' => array(
            'bir_specimen' => 'bir_specimen',
            'bir_image' => 'bir_image',
            'bir_locality' => 'bir_locality',
            'bir_view' => 'bir_view',
          ),
        ),
      ),
      'instance' => array(
        'field_name' => 'bir_collection_node',
        'entity_type' => 'field_collection_item',
        'bundle' => 'bir_collection',
        'label' => '',
        'cardinality' => 1,
        'description' => '',
        'widget' => array('type' => 'node_reference_autocomplete'),
        'display' => array('default' => array('type' => 'node_reference_default')),
      )
    ),
  );

  // Loop through fields array and create field and instance
  foreach ($fields_array as $field) {
    // Check if field already exists
    if (!field_info_field($field['field']['field_name'])) {
      field_create_field($field['field']);
    }

    // Check if instance exists
    if (!field_info_instance($field['instance']['entity_type'], $field['instance']['field_name'], $field['instance']['bundle'])) {
      field_create_instance($field['instance']);
    }
  }
}

First field in the $fields_array array is the field_collection type field that you add to your node entity. (field_name: bir_collection)

The second field in the array is the field which is added to your field_collection_item entity (Notice the bundle in the instance is same as your field_name on node: bir_collection. This is how the connection is made). In this particular example, it's a node_reference type field, but this can be any other field type that's available to your Drupal instance.

The order has to be in this sequence, since you need to add the field_collection type field to your node to create the field_collection_item entity, then you add the fields to your field_collection_item entity.


How to load paragraphs fields in hook_form_alter to disallow access? I have a field inside a paragraph referenced in an taxonomy term.

/**
 * Implements hook_form_alter()
 */
function custom_general_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
  switch ($form_id) {
    case 'taxonomy_term_application_category_form':
        $entity = $form_state->getFormObject()->getEntity();
        kint($entity);
        break;
  }
}

Inside Paragraph field named field_test_para,
I have a text field named field_text,
how can I fetch array structure of field_text in order to hide the field_text and how can disallow access to the text field. So far, I have managed to get the taxonomy entity and looking on how I can fetch paragraph entity and then alter the #access parameter of text field within it.

Maybe you can use a preprocess paragraphs function which will target it more easily

function mymodule_preprocess_paragraph__myparagraph(&$vars)
{
    if ($vars['view_mode'] == 'full') {
        $parag = $vars['paragraph'];
        if (SOME LOGIC HERE){
        unset($vars['content']['myfield']);
        $var['field_removed']=true;
    }
}

The key point is to replace __myparagraph with the id of your paragraph

This example show you:

How to access the paragraph object $parag = $vars['paragraph'];
How to handle your logic only for a view mode ($vars['view_mode'] == 'full')
Remove a field unset($vars['content']['myfield']);
You can test the variable field_removed in your twig template to not run the code to display the field (optional)

Oups, it looks like you are asking to alter a paragraph's form...
For this you can use hook_field_widget_paragraphs_form_alter

function maymodule_field_widget_paragraphs_form_alter(&$element, FormStateInterface &$form_state, $context)
{
    switch ($element['#paragraph_type']) {
        case 'myparagraphs':
            $term = $form_state->getFormObject()->getEntity();
            //Check if paragraph is inside a form term
            if($term && ($term->getEntityTypeId()=='taxonomy_term')){
                $voc=$term->bundle();
                //Check if it is the desired voc
                if($voc=='my_voc'){
                    //unset($element['subform']['field_to_be hidded']); //to hide only one field
                    $element=[]; //to hide all the form
                }
            }
            break;
    }
}

Hope this help


How can I prevent "Log in to post comments" from displaying for anonymous users? How do I remove the "Log in to post comments" from the bottom of my content in Drupal 8 while keeping old comments visible to all and allowing existing registered users to still comment? Basically, I don't want anonymous users to find my login page, ever. These means no CSS hide or Javascript solutions (bots will still follow the link).
So, if comments exist on a node:
I want anonymous users to:

See the comments as usual
NOT see any sort of "add comment" link
NOT see any sort of "login/register" link either

I want authenticated users to:

See the comments as usual
See "add/reply" comment links as usual

If comments DO NOT exist on a node:
I want anonymous users to:

See NOTHING at the bottom of the node

I want authenticated users to:

See "add comment" link as usual

You can do it using hook_preprocess_HOOK
The following hooks should be placed in YOURTHEME.theme file:

Remove comment links from node for Anonymous user:

    /**
     * Implements hook_preprocess_HOOK().
     */
    function YOURTHEME_preprocess_links__node(&$variables) {
      if (\Drupal::currentUser()->isAnonymous()) {
        unset($variables['links']['comment-forbidden']);
      }
    }

Remove links from the comments for Anonymous user:

/**
 * Implements hook_preprocess_HOOK().
 */
function YOURTHEME_preprocess_links__comment(&$variables) {
  if (\Drupal::currentUser()->isAnonymous()) {
    unset($variables['links']['comment-forbidden']);
  }
}


How to override individual blogs/% page? I've got a question about overriding the default blogs/username page with Views.
I've created a new view with a page display with blogs/% as path, and set arguments to user:name. I'm typing blogs/rustam, the default page of individual blog is displayed. How do I  correctly override the blog page with Views?

blogs/[username] is the path alias; the internal path is blog/[uid]. Change your view to use the internal path blog/%.

Where % represents the passed value that you are capturing like the userid. Then you will need to add an argument as well like User: User ID so that everything is consistent


Get the ID that for the node that has been just created I am trying to get the node ID that I have just created. If I do the following code from this answer.

$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof \Drupal\node\NodeInterface) {
  // You can get nid and anything else you need from the node object.
  $nid = $node->id();
}

I implemented hook_ENTITY_TYPE_view() (just to test the code), but it gets the ID for all the nodes, while I want the ID of the node that has been created to modify a field value for that node. Is this possible?

Should I use the code I shown in a hook_form_alter() implementation or maybe inside a form submission handler?

If you need to alter the value of a node field right after the node has been created, you don't need that code. You just need to implement hook_ENTITY_TYPE_presave() and verify the node is new.

function mymodule_node_presave(EntityInterface $entity) {
  if ($entity->isNew()) {
    // The node has been created.
    // Access the node field using $entity.
  }
}

If then, for any reason, you need the node ID, you can access it with $entity->id().

I used hook_ENTITY_TYPE_presave(), assuming the node needs to be saved with the new field value.


How to embed a view into the teaser of a node? On the main page, I have a view that lists 3 items (3 boxes). One of them is linking to the news section. Right now, it's only a plain node and only the teaser is displayed on the front page.

If it's possible, I want to include the top 3 news headlines within the teaser of this node. Basically this will be a view inside of a teaser that is also listed to the front page by a view.

I might succeed with this method but I want to avoid using PHP as a text format. Should I just create a module and insert the view into the teaser by code? Is there a more convenient way?

You can install and activate the Field views module, and add the field type to your content type. Configure it for your view.

Then edit your content type, and under 'Manage Display' configure the field to be visible in your teaser.


How to do a hard redirect when in Ajaxified form? I have an Ajax multistep form and I want to redirect user to specific route when some conditions are met (specifically if the user is inactive for more than N seconds and the form is submitted after this limit).
I wanted to do the redirection in the validation handler but no luck. So I tried with a submit handler but still no luck. I'm quite buffled.
I tried to return a redirect response, I tried to set redirect response on the form state, I tried to set redirect on the form state, I have tried to disable form state rebuild, I have tried to copy the goto action logic and use an event dispatcher, I tried to unset the \Drupal\Core\Form\FormBuilderInterface::AJAX_FORM_REQUEST from request but still no luck.
I could maybe return the redirect in an Ajax callback as redirect command but I want to make this work with disabled JS so invoking window.location would not be enough.

In my case (D8), I just had to implement the RedirectCommand in my AjaxSubmit :

Code of the submit button :

$form['submit_' . $this->uniqueIdentifier] = [
  '#type' => 'submit',
  '#value' => $this->t('Submit'),
  '#attributes' => [
    'class' => ['btn', 'btn-primary']
  ],
  '#ajax' => [
    'callback' => [$this, 'submitModalFormAjax'],
    'event' => 'click',
  ],
];

Code of the submit callback:

public function submitModalFormAjax(array $form, FormStateInterface $form_state) {
  $response = new AjaxResponse();

  if ($form_state->hasAnyErrors()) {
    // Do validation stuff here
    // ex: $response->addCommand(new ReplaceCommand... on error fields
  }

  else {
    // Do submit stuff here

    $url = Url::fromRoute('page_route');
    $command = new RedirectCommand($url->toString());
    $response->addCommand($command);
  }

  return $response;
}

Do not forget to declare :

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\RedirectCommand;
use Drupal\Core\Url;


Custom libraries and dependency injection I have been using D7 for a while, new to D8; also have a fair amount of experience with Laravel/Lumen and dependancy injection (DI).  One of the big sell's of D8 is the new OO structure, and specifically the Symphony DI system.

So to test this out, I want to develop (port some of my old D7 code) to a D8 custom library, that will 'inject' when needed, and I do not want to do this as a module (I got that right; the objective is to have a PHP library class).

Given some of the documentation I read, I created a folder called /libraries/my_library, and for the hell of it I added a PSR4 mapping to /composer.json like so:

"Drupal\\CustomLib\\": "libraries"

For the record, I tried it without Drupal\\ as well - makes no difference.

In /libraries/my_library/scr/myClass.php I have a single class myClass.  I also added a my_library.services.yml

services:

  myClass:
    class:   CustomLib\mylibrary\myClass

And in my custom theme file I simply tried

use CustomLib\mylibrary;

function quirk_preprocess_html(&$vars) {
  $tools = Drupal::service('myClass');
}

which results in

Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service

Can someone point me in the right direction please.  What am I missing.  I am assuming Drupal is not scanning the /libraries/my_library folder for the services definition - but how do I get it to do so?

OK people, I played around with a couple of options, but the bottom line is, if you want to create your own 'services' class, specifically for dependancy injection, it has to be tied to a module.

So - I created a custom module.  The actual module file is empty

<?php

Also created the services definition / config file my_module.services.yml and then critically, your services class files should go in a sub-folder /src.  Since it is a service, you will need an interface and implementation class.


What do I have to do to get hook_form_alter picked up? Trying to move from Drupal 7 to Drupal 8.  First step is to get a custom module with hook_form_alter() and the Devel module working so that I can see how bad I am messing things up.

To do so, I made a custom module with the following files.

mymodule.info.yml

name: My Module
type: module
description: "Custom module"
package: Custom
core: 8.x

mymodule.module

<?php

function mymodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  dpm($form);
  print_r($form);
}

Other steps

I enabled both the Devel module and this custom module.
I gave anonymous users permission to view devel information.
I made sure the Status block was enabled on the Block Admin page.
I cleared all caches via the Pantheon admin interface.
I tried using print_r($form), dpm($form), and var_dump($form).

However, when I refresh /user/login, I don't see any output from dpm(), so the hook isn't getting picked up for some reason.  What else do I need to do?

It turns out this was something related to MultiDev, a Pantheon-specific feature.  By cloning back and forth between the main dev branch and my multidev branch, I was able to get the custom hook_form_alter() to work.


Best practice: content types with unique machine names We have a module install script that auto-generates content types.

The content type machine names are based on text field data inputted by a user using a custom form. For example:

User title = 'Technical' => Auto-generated machine name = technical_comp

User title = 'Specialist Claims' => Auto-generated machine name = specialist_claims_comp

… and so on.

For the module to be robust, it needs to create unique 32 character machine names where there are two text fields with the same data.

Is there best practice around this?

I was thinking something along the lines of:

User title = Technical => Auto-generated machine name = a1_comp

User title = Specialist Claims => Auto-generated machine name = a2_comp

… which would give us plenty of scope but would require some kind of content type count.

Counting content types should be as easy as:

$result = db_select('node_type')
        ->fields('node_type')
        ->execute();
$num_of_results = $result->rowCount();

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