Why Won’t If “Drupal\node\NodeForm” Work?

I need to determine what kind of object a form is. When I dpm the class, it says Drupal\node\NodeForm . So, the following should work:

if (get_class($form_state->getFormObject()) == "Drupal\node\NodeForm") {

But it does not! I’ve been forced to do stupid things like this:

if (get_class($form_state->getFormObject()) != "Drupal\node\Form\DeleteMultiple") {

DUH MOMENT! I finally figured it out today. VS code highlighted this out of the above first line of code:


DUH! PHP is reading this as a new line! Wow.

New code that works is:

if (get_class($form_state->getFormObject()) == "Drupal\\node\NodeForm") {

This does make sense now that I think about it!

How To Determine If You’re On A Node In Drupal 8

Preamble: If you don’t know how yet to embed media into Drupal, I recommend looking at how to embed stuff into Drupal 8 by Lullabot. It doesn’t go over everything (since you definitely need custom stuff) but it’s a good start.

We are using Entity Embed along with a few other contributed Drupal modules to be able to insert media into the WYSIWYG. I created a custom module in order to do this. I use hooks such as
HOOK_preprocess_entity_embed_container and HOOK_form_entity_embed_dialog_alter in order to get this functionality to work. I also have a template which outputs the media. Images output as img, files output as a link with file name and opens in a new window.

We were now asked to attach a content type in our content. Instead of creating a field, I wanted to be able to insert this content into the WYSIWYG.

After modifying my custom module which will render the entity, I ran into an interesting issue. I did not want to render the full entity in the WYSIWYG. First, it would render the whole thing and it would not put in the stuff we put into our .theme file. It didn’t look right.

I only want the entity to be rendered on the node screen (i.e. in our public facing theme… when it’s actually on a node).

The template in our custom module renders it in both the WYSIWYG and on the “node” side. So… how do I get it to only render on the “node” side?

There are several states when it’s on the “node” side. I’m adding a variable in HOOK_preprocess_entity_embed_container which will tell the template to render the entity or else just say the name of the node it’s inserting. Just using
$node_info = \Drupal::routeMatch()->getParameter("node"); doesn’t work. $node_info is NULL on preview. However, if you also do:

$node_info = \Drupal::routeMatch()->getParameter("node");
if (empty($node_info)) {
	$node_info = \Drupal::routeMatch()->getParameter("node_preview");

then a:

if (gettype($node_info) == "object") {
	$variables["node_render"] = true;

which will tell the template to render the entity via the {{ children }}. So far this code hasn’t triggered any PHP or Drupal errors or warnings (fingers crossed).

Not sure if I’ll need this again but it’s probably handy to have since we are also using workbench, have nodes in draft, and have a preview.

Hook “More” Link In Views For Drupal 8

I needed a way to modify the Custom URL in the Pager for the More link for Views. I added a Contextual Filter so that the particular display can be put onto any page and it will display items from the current office.

This URL needs to be dynamic and change depending on where on the site this view is placed.

What Views needs here is some tokens!

I looked into hooking “container” but that seems messy as I’m not sure where else it’s used. It’s doable that way but I primarily tried to look at the view.

In my preprocess, THEME_views_pre_render, I tried to dig further into the ViewsExecutable class. It turns out, the display_plugin method was what I was looking for.

Here’s some of my code:

function THEME_views_pre_render(\Drupal\views\ViewExecutable $view) {
	// target your view and display
	if (($view->id() == "my_view") && ($view->current_display == "my_display")) {
		// this is just what's actually in the field to begin with... i.e. "success-story" in my screen shot above
		$ending_part_of_uri = $view->display_handler->getOption("link_url");

		// call a function or whatever to get the part of your uri
		$starting_part_of_uri = _THEME_function_to_dynamically_get_URI();

		// now set the link to whatever
		$view->display_handler->setOption("link_url", $starting_part_of_uri . $ending_part_of_uri));

Default Value Of Today’s Date On Timestamp In Drupal 8

One of the stupidest things in Drupal 8 is the Timestamp field. If only I knew what I know now. All well, we’re stuck with it.

Its default value cannot be set to today’s date. When saving the field as null in the field settings, going to a new node, the default value is when you saved the field. Ours was two years ago since that’s when I started working on this site. So default dates for our Timestamp field were like “09/04/2018 02:43:02 PM”.

Not good. How do you make the default date the date of the new node (like today’s date and time)?

I first installed a patch on a ticket on drupal.org (patch #14) which allowed the field setting to be null. Since the Timestamp field sucks, it doesn’t give you the option of today’s date like the Date field does. So, I had to add to our custom module the way to do that.

// see if we need to worry about the publication date
if (isset($form["field_publication_date"])) {
	// if it's a new form
	if ($form_id == "node_" . $your_content_type . "_form") {
		// set the default value to a new date time (which by default is "now")
		$form["field_publication_date"]["widget"][0]["value"]["#default_value"] = new DrupalDateTime();

	// end if we have a field_publication_date

This code can go inside a preprocess like hook_form_alter. You also don’t need to do it the way that I did with the $form_id. There might be a new node hook somewhere that you could add this to maybe. Obviously, the field_publication_date should be changed to whatever your Timestamp field machine name is called.

Blocks Only Seen By Administrator In Drupal

It really does erk me that Drupal doesn’t have an option for administrators in the Show blocks for specific roles when editing a block.

I needed a customized menu for a role (reg_user). This role had limited, basic access to do things. They needed to add news articles (a news content type I created) as well as edit them and edit pages. Rather them clicking Create content –> News, I just wanted a link on the left navigation, as well as a few other customizable links.

I could have edit the navigation menu through Administrator –> Site building –> Menus –> Navigation, etc etc. However, that would also change for the administrator as well as the role I wanted it to be customized for.

Well, long story short, after a while of research, it seemed the only option was to create another menu.

I did create another menu.

Then I ran into another problem. How to display the menu (Reg User Menu) to the reg_user and NOT the administrator, and the Navigation menu to the administrator and NOT the reg_user. It seemed easy enough to do via the specific roles, however, that doesn’t have the option for an administrator.

I also had another issue, the menu was to not be displayed on node/1 (the home page).

To accomplish all of this:

Reg User Menu – It’s a block when you create a new menu. I gave access to the reg_user. It doesn’t show up for administrators.

Navigation menu – No options were chosen for Show block for specific roles. Instead I did the following in the ‘Navigation’ block:

Page Specific Visibility Settings In Navigation BlockThe code being:


$r = false;

if (user_access(‘administer’)) { $r = true; }
if (($_GET[“q”] == “node/1”) || ($_GET[“q”] == “node/1/edit”)) { $r = false; }

return $r;


The if statement with user_access tests if it’s an administrator, if so, display the block. The $_GET[“q”] if statement tests if they’re on the home page, if so, don’t display the block.

I really wish Drupal had easier ways to do this. Like I said before, it’d be a lot easier if they only had an Administrator option for the Show block for specific roles.

Currently, I’m dealing with a module issue that needs Clean URLs (which is disabled on our Windows system).

I hope someone can get help from this not well written post…

How To Insert Images Into Links In Drupal

I only struggled with this for about an hour. I’m not sure why Drupal hasn’t thought of this before, but it would be nice to have images as links once in a while. I needed one for my menu… a home link that was an image of a little house (how cute).

I read on a blog to edit the theme_menu_item_link function located in includes/menu.inc . I then added my <img tag to the Description. Well, that didn’t work. I investigated it further and looked at the code and instead put it in the Menu Link Title. That didn’t work either. I even tried the PHP function html_entity_decode, but that didn’t work either. It was still escaping the characters.

Anyway, after googling and reading up on how to do it, I tried to edit the template.php file with no luck. I read some other blogs and tried to edit some other files but it still kept escaping the code. I didn’t want to mess with the other files Drupal had put there.

I finally formed my own solution. I decided to edit the files Dupal put in. I looked for the l() function which is the function that actually forms links.

I added the following to the function l() in the file includes/common.inc on line 1598, right after the default options are declared in the $options array:

if (strpos($text, ‘<img’) === 0) {
$options[‘html’] = TRUE;

Yes, I know it’s unsafe but that’s the only way I could get it to NOT escape. I can now add HTML img script to the Menu Link Title and it display an image.

I’ll make this brief. I don’t know why Drupal didn’t think about images in link lists before. You think that would be obvious. The more and more I learn about Drupal, the more and more I realize how LESS flexible it is than I thought. I will say at least they have a community that can help, which is something that Microsoft seems to lack.

Come on, Drupal, think common sense.

Enabling PHP Input Into Drupal

After a while of wondering how the hell I’m supposed to add PHP into Drupal, and many times trying it in blog entries, posts, and blocks, nothing came out of it. It would always display the PHP code and not evaluate it. I didn’t get my PHP cert for nothing, ya know?

I actually found this on a forum of someone else having the same problems. They didn’t exactly show you the correct path of where you change it but I remember the screen before and I was able to get back to it.

If you go to Administrator then Site Building then Modules, it is the PHP filter. You need to check it for PHP code to be in your Input formats.

Yay. Now I’m on my way!

Inserting Data Into A Form Input Array

I’ve also struggled with this one for a while, off and on. I have a form that has several textarea’s. Their data is put into an input array. It is looped using a for loop in PHP. Ex:

// for loop in PHP here

<label>Data:</label><br />
<textarea name="data[]" id="data[]" rows="5" cols="40"><?= $data[$x]; ?></textarea> <a href="javascript:popUpWindow('popupsearch.php?frm=input_form&amp;fld=data[]&amp;select_multi=yes', 700, 300);">Lookup Data</a>

// end for loop

This is generated using PHP (a for loop). Basically, the user decides how much data they want and they type it in, or they can look up data. When they click Lookup Data, a window pops up with a search feature for them to search for data. They can choose multiple items to insert into the form. When they do, it closes the popup and inserts the data into the form.

Sounds simple, right?

The problem was with the array. My guess is XHTML doesn’t use arrays of id’s (yet). The syntax above is what I tried (and failed) to put before. The work around is:

<label>Data:</label><br />
<textarea name="data[]" id="data_<?= $x; ?>" rows="5" cols="40"><?= $data[$x]; ?></textarea> <a href="javascript:popUpWindow('popupsearch.php?frm=input_form&amp;fld=data_<?= $x; ?>&amp;select_multi=yes', 700, 300);">Lookup Data</a>

The id is no longer in an array. The name is what is actually used later in PHP to get the value(s), so there’s no rewrite of code on the backend side.

I read an article (or I heard) that in HTML 5 when it becomes a standard, they will be combining the id and name elements of inputs. That’s the only problem I can forsee with this code not being able to be used later. I’d have to modify this code and rewrite the backend to recognize each textarea as its own entity instead of an array.

Displaying Quotes In Alerts Using JavaScript And PHP

I’ve been struggling with this problem off and on now for the past like six months. The issue is properly displaying single and double quotes in JavaScript on a onclick action. PHP is being used to get the data for the string.

The data without single or double quotes displayed fine in the alert box, but the other data didn’t.

In a nut shell, I needed:

<a onclick="javascript: alert('$data');">?</a>

The trick was escaping $data to display the proper PHP first, then JavaScript.

The $data string I kept testing was:

Has the ability to quote the Godfather series on command. Must be able to complete a quote or a scene by the slightest dialogue.

“Go to the mattresses!”

As I said, I tried just about everything trying to get $data to display single and double quotes in the alert box. I started simple by replacing the with /’ and with /”, to no avail. I also tried using the htmlspecialchars function, but that didn’t work either.

Furthermore, I tried to replace the double quotes with single quotes and escape the string. It still didn’t work.

When I finally got close to solving the problem, I realized it wasn’t necessarily escaping the quotes, it was also escaping the line breaks. Since PHP and JavaScript have the same line break escape (\n), it was a little tricky.

I finally got a script off the internet to escape the string and put the special characters into their HTML entities. It didn’t work, but I built on that same idea.

My script is now:

$data = preg_replace("/\r?\n/", "\\n", htmlspecialchars(str_replace("'", "\'", $data)));

echo "<a onclick=\"javascript:alert('$data');\">?</a>\n";

Works like a charm.