# Question
Title: How to display google map field in hidden div?
I have a Google Map Field in my form. I'm editing the theme of the form and I'm using a jquery but the map is broken.

The map is inside a div and the code of the template is this:

And here is the Jquery:

```
$("#show-block-3").click(function () {
         if ($('#hidden-block-3').is(":visible")) {
             $(this).html($(this).html().replace(/Hide/, 'Show'));
                var center = map.getCenter();
                google.maps.event.trigger(map, "resize");
                map.setCenter(center);

         } else {
              $('div#hidden-block-1').hide();
              $('div#hidden-block-2').hide();
              $('div#hidden-block-4').hide();
              $('div#hidden-block-5').hide();
              $('div#hidden-block-6').hide();
              $('div#hidden-location-block').hide();
         }
         // Do it afterwards as the operation is async
         $("#hidden-block-3").slideToggle("slow");

});(jQuery);

```

I just tried this:

```
var center = map.getCenter();
google.maps.event.trigger(map, "resize");
map.setCenter(center);

```

But the result is still the same. I don't know where else to put that code.

Am I missing something? Does anybody know how to fix this? I'm not using vertical tabs or any tabs that group field module has in the template and in the form. I would to stick with the custom code that I already have. Just need to fix the map.

Thank you!

# Answer
If anyone is still interested in this answer, I managed to achieve this by making a css class:

```
.hide-map {
    opacity: 0;
}

```

I did mine in angularjs, but in JQuery I'm sure you could use some sort of toggle to enable/ disable the css class when it has loaded.
> 0 votes

---
Tags: javascript, google-maps
---


# Question
Title: How to load some selected files in Media Browser
I have a run time list of image files with their fid's. I am using Media module to handle image files. I want to load only specific set of image files fid's in the media browser on node add/edit page.

Please help me to achieve this specific stuff.

# Answer
This is little bit tricky. Media browser generally opens all the files. So, when we present the file field in the front end, we need to pass file type (Even we can pass fids too, after uploading the files).

On the views side either using views\_query\_alter or a filter in the views we need to filter them out.

Using this scenario we can alter media browser files options.
> 1 votes

---
Tags: media
---


# Question
Title: Delivery Date Changes Price field value with New Custom Field
I got project with following requirements:

1. The customer should be able to select **delivery date**(date popup) in the **checkout form**.
2. The administrator can set **special delivery date**, in configuration settings.
3. If the customer select a **delivery date** that matches with **special delivery date**, the **prices** will **change**.
4. There are **2 price field** in **1 product reference**. The **default price field** and **custom special price field**.
5. **Price value** will **change** according to the **delivery date** that the customer selected.

For example:

Case 1:

1. The **admin** set Special date to be: Feb 14, 2016
2. The **customer** selected delivery date: March 2, 2016
3. The final product price uses the **default price field** value.

Case 2:

1. The **admin** set Special date to be: Feb 14, 2016
2. The **customer** selected delivery date: Feb 14, 2016 (**match**)
3. The final line item product price will use the value that was set in the **custom price field**.

What would be the workaround with this one. I feel stuck with my module. I was thinking if I need to use rules instead. Thanks in advance.

# Answer
Rules will be the best option in the above mentioned cases. You can use "data validation" to compare both fields and set value of the "product price" field accordingly
> 0 votes

---
Tags: 7, commerce, rules
---


title: Managing large taxonomy

text:
# Question
Title: Managing large taxonomy
I've got a vocabulary with 700 terms and Views term hierarchy weight field enabled (version 7.x-1.6). When adding or movind a term, it starts to recalculate depths for every term, and the "Computing the weight and depth of each term" screen takes more than 3 minutes in a site that is not in production. Vocabulary is not more than 3 levels deep. Drupal version is 7.44.

I disabled the VTHWF module for comparison, and the processing time for adding /moving terms was cut to a tenth, so I thought "great: disable it, move and create, and then re-enable it!"... BUT the missed terms' depths were not recalculated as the module was reenabled.

Any help possible? thanks

# Answer
Firstly it depends on your local environment. 700 Taxonomy terms are not a lot but calculation might be affected if your local environment is not powerfull enough. To mitigate your performance drawbacks take two steps.

1. Make sure you are using php 7 because it actually has a significant performance increase.
2. Increase your php memory limit to 128MB. Find the memory\_limit variable in php.ini file and add 128MB next to it.

Now in the case of your calculation of depth after re-enabling the module issue I guess the correct path to take is the issue queue of the module itself. Issue Queue
> 0 votes

---
Tags: taxonomy-terms, performance
---


title: How do I display content on slideshows?

text:
# Question
Title: How do I display content on slideshows?
I am using the Jssor Slider module. My slider works, but the content type *Jssor slider*, where text is displayed on images, is not working on Drupal 8.

I want to display content on slideshows like shown on http://www.jssor.com/demos/content-slider.slider. How can I do this?

# Answer
I've tested the module and tested.It works. Seems you missed the pre-configured **view** provided by this module.

You can find it at `http://www.example.com/jssor_jssor`. Find the **jssor** views in the view list. You can do slider settings in the view itself.

Seems you've selected 'Content' instead of Jssor in view. If you select 'content' it display normal slider. So in order to display text on slider make sure to add **Jssor** in **show** under FORMAT options.
> 0 votes

---
Tags: javascript
---


# Question
Title: How to code multiple values field in Views PHP?
I need help setting up ViewsPHP to evaluate 3 pieces of data? (I barely know any PHP)

## ViewFields

I have a View with three embedded Viewfields:

**Node count** $row-\>view \[views\_field\_view\_view\]

**Time ago (1 unit)** $row-\>view\_1 \[views\_field\_view\_view\_1\]

**Success rate** $row-\>view\_2 \[views\_field\_view\_view\_2\]

## Value code

In the Value Code text area I want to call all the values. I currently have:

```
return $data;

```

## Output code

In the Output Code I want to do something like this:

```
<?php
if ($row->view >= 5 AND $row->view_1 >= 5 AND $row->view_2 >= 80) {
    echo "Amazing person";
}
elseif ($row->view >= 3 AND $row->view_1 >= 3 AND $row->view_2 >= 70) {
    echo "Good person";
}
elseif ($row->view >= 1 AND $row->view_2 >= 60) {
    echo "Interesting person";
}
else {
    echo "Content needed";
}
?>

```

It's only outputting "Content needed" so what have I done wrong?

EDIT: Updating to 7.x-2.x-dev makes this work.

# Answer
> 0 votes
Structurally, your code looks fine, it's probably because

`$row->view` = `<div id="views-view--view-name"><div>5</div></div>` basically the 5 has HTML tags around it.

so `<div id="views-view--view-name"><div>5</div></div>` does not equal 5

You can use the PHP strip\_tags() function to get rid off the tags.

```
if (strip_tags($row->view) >= 5 AND strip_tags($row->view_1) >= 5 AND strip_tags($row->view_2) >= 80) {

```

So try this:

```
<?php

$a = strip_tags($row->view);
$b = strip_tags($row->view_1);
$c = strip_tags($row->view_2);

if ($a >= 5 AND $b >= 5 AND $c >= 80) {
    echo "Amazing person";
}
elseif ($a >= 3 AND $b >= 3 AND $c >= 70) {
    echo "Good person";
}
elseif ($a >= 1 AND $c >= 60) {
    echo "Interesting person";
}
else {
    echo "Content needed";
}
?>

```

**PS**: no need to have anything for value code `return $data;`.

---
Tags: 7, views
---


# Question
Title: How do I correctly cache a themed menu output?
In `mytheme_preprocess_menu()`, I am altering the main menu:

```
function mytheme_preprocess_menu(&$variables, $hook) {
  $node = \Drupal::routeMatch()->getParameter('node');
  if ('menu__main' == $hook) {
    if ($node) {
      _mytheme_menu_replace_with_project_items($node, $variables['items']);
    }
  }
}

```

In `_mytheme_menu_replace_with_project_items()`, I check whether the current node is a project node, and show that node's submenu instead.

When I visit the node the menu gets displayed, but when I add another node with another project reference, the menu of the former node gets displayed.

How can I correctly cache that?

I tried with the following code, but it didn't work.

```
$variables['#cache']['tags'][] = 'node:' . $node->id();
$variables['#cache']['contexts'][] = 'route.name';
$variables['#cache']['contexts'][] = 'theme';

```

# Answer
> 0 votes
Okay, so this combination worked...

```
$variables['#cache']['tags'] = ['node:' . $node->id()];
$variables['#cache']['contexts'] = ['route', 'theme'];
$variables['#cache']['keys'] = ['entity_view', 'node', $node->id()];

```

I dont see a huge difference to my first attempt but whatever!

---
Tags: 8, caching, theming
---


title: How do I filter the current year?

text:
# Question
Title: How do I filter the current year?
Initially, I have installed the Token module and created a Views block containing years.

I want to filter out the current year from the block (it should not show the current year).

In filter criteria, I have changed content:year (\[current-date:custom:Y\]), but it is not filtering the current year, and it is showing as follows:

* 2013(3)
* 2014(5)
* 2015(6)
* 2016(2)

I am expecting the output to be as follows:

* 2013(3)
* 2014(5)
* 2015(6)

How can I achieve this? Any help is greatly appreciated.

# Answer
You may want to check if using the Views Date Format SQL module could be a solution. Here are some quotes about it (from its project page):

> ... allows to format date fields using SQL.
>
> The core functionality is to remove the date formatting from render() and put it in query(). I.e. format date values using SQL's DATE\_FORMAT rather than PHP's format\_date. This is achieved by assigning a new default handler to node 'created' and 'changed' date fields. This handler extends and overrides views's build in views\_handler\_field\_date.
>
> The UI is completely unobtrusive, only a single checkbox "Use SQL to format dates" is added to the handler configuration popup.

Your question is not about creating charts in Drupal, but you may want to refer to this comment also for an example of how we typically use it within the Charts module.
> 0 votes

---
Tags: 7, views, tokens
---


# Question
Title: How can I get the field settings in a field preprocess hook?
How can I get the field settings in a field preprocess hook?

# Answer
You can fetch the field settings in a preprocess hook by using the following code.

```
function YOUR_THEME_preprocess_field(&$variables) {
  if($variables['element']['#field_name'] == 'field_event_date') {
    $node = $variables['element']['#object'];
    $field_name = 'field_event_date';
    $instance = field_info_instance('node', $field_name, $node->type);
    $display = field_get_display($instance, 'default', $node);
    $variables['event_date_formate'] = $display['settings']['format_type'];
  }
}

```
> 0 votes

---
Tags: 7, entities
---


# Question
Title: Malware on D7 website - Blacklisted by Google
I want to tell you about the malware attack to my Drupal website. Not just for your suggestions but also to create something helpful to anybody tha could suffer for the same problems. Well...

---

## INITIAL SETUP

* Drupal 7.9
* Activated modules:
    + CORE: Block, Contextual links, Database logging, Field, Field SQL storage, Field UI, File, Filter, Image, List, Locale, Menu, Node, Number, Options, Overlay, Path, PHP Filter, RDF, System, Taxonomy, Text, Toolbar, User
    + CCK: Multiselectd
    + CHAOS TOOL SUITE: Chaos tools
    + DATA/ORA: Calendar, Date, Date API, Date Popup, Date views
    + FIELDS: Email, Field permission, Link
    + OTHER: Google Plus One +1, Pathauto, Token, Weight
    + SHARING: Share this, Share this block
    + TAXONOMY MENU: Taxonomy menu
    + VIEWS: Views, Views PDF Display, Views PHP, Views UI
    + OTHER MODULES THAT I REMOVED: CKEDITOR, VIEWS\_SLIDESHOW, IMCE, DOMPDF, PRINT, WYSIWIG

---

## MY SETUP ERRORS

* In order to satisfy the custome, I modified some of the modules and I've never update them (AUCH!)
* The customer was in posses of the login data, and maybe his computer wasn't safe (MMM...)
* I didn't have a copy of the webiste, because I trusted on the provider weekly backup (DOH!)

---

## ATTACK EXTERNAL SYMPTOMS

* All the link of the homepage redirected to a malware website
* Google blacklisted the website
* Critical alert on the Google Webmaster Tools panel

---

## FTP SYMPTOMS

* Lots of "strange" files: mainma3.php (I found this one in every folder!), functoins.php, sum75.html, wlc.html, aol.zip, chase.zip, chaseverification.zip, 501830549263.php, wp-conf.php and a dozen of wtmXXXXn.php (dove X = numero) in the root folder. All these files was plenty of malicious functions (unescape, base64\_decode, eval, etc.)
* Install.php was modified with a long line of malicious code
* To EVERY javascript files was appended this line of code: ;document.write('');
* The weekly backup was also infeceted
* Dozen of repeated "strange" request, found on the Drupal log panel (my domain is obscured with the string "-----"):
    + index.php?q=ckeditor/xss \> Notice: Undefined offset: 5 in eval() (linea 29 di /web/htdocs/-----/home/modules/php/php.module(74) : eval()'d code(1) : eval()'d code).
    + -----/user?destination=node/add \> Failed login by shadowke
    + calendar/week/2012-W19?year=2011&mini=2012-12 \> page not found
    + misc/\]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P.\_default=\[1, \> page not found
    + misc/)h.html(f?c( \> page not found
    + mail.htm \> page not found

---

## RECOVER \[Thank to this article: http://25yearsofprogramming.com/blog/20070705.htm\]

1. I've put the website on Maintanance mode (error503.php + .htaccess). Traffic open just for my IP Address \[see this useful guide: http://25yearsofprogramming.com/blog/20070704.htm\]
2. I've downloaded the whole website in local
3. I've searched and removed the strange files \> I found forty of them
4. I've searched the files for these worlds \[with the freeware AGENT RANSACK\]: eval(base64\_decode($*POST\["php"\])), eval(, eval (, base64*, document.write, iframe, unescape, var div\_colors, var \_0x, CoreLibrariesHandler, pingnow, serchbot, km0ae9gr6m, c3284d, upd.php, *timthumb*. \> I've acted in one of the follow ways: a) I've replaced eval with php\_eval() (the eval safe version of drupal); b) I've wrote down the suspected modules; c) I've compared the code with the fresh downloaded module; d) I've removed all the malicious code (see the javascript mentioned above)
5. I've searched for mohanges in the file system \[with the freeware WINMERGE\]
6. I've identifyed some suspected modules, thank to the list written at the point 4 above, and thank to some researches on Google (name\_of\_the\_module security issue, name\_of\_the\_module hacked, etc...) and on Secunia \[http://secunia.com/community/advisories/search\]
7. I've scan my computer (Avast, Search&Destroy, Malwarebytes Antimalware) \> I didn't found any virus or spyware
8. I've changed all the logins (ftp, cpanel, drupal admin panel)
9. I've reloaded the whole website
10. I've removed all the suspected modules: CKEDITOR, VIEWS\_SLIDEWHOW, PRINT, DOMPDF, IMCE, CAPTCHA, WYSIWIG, WEBFORM.
11. I've tell the whole story to the provider assistance
12. I request Google for a revision (they did it in 12 hours)

---

## DRUPAL LOG NOW

dozen of these messages \- wtm4698n.php?showimg=1&cookies=1 \> page not found \- fhd42i3d.html \> page not found \- wp-conf.php?t2471n=1 \> page not found \- -----/user?destination=node/add \> Failed login by Elovogue

---

## LESSONS LEARNED

* Never touch the modules, so you can update them
* Keep all the login in a safe computer / Use a safe computer to work on the FTP
* Search for any security issue before installing a module
* Keep a clean copy of the website somewhere

---

## MY QUESTIONS:

* What kind of attack I've received?
* There are other unsure module in my installation?
* What can I do yet?

Thanks to everybody for your patience!

# Answer
> What kind of attack I've received?

It's really hard to say. It could be a desktop virus, or a php execution via one of the modules (or insecure configuration). It's good that you seem to have blocked it.

> There are other unsure module in my installation?

You should download a "good" copy of each module from drupal.org and compare them. If you haven't yet, put the whole site in revision control (git) and make the live site a checkout from git so you can quickly see "git status" if anything is changed and then "git reset --hard origin/master" to undo the changes.

> What can I do yet?

In addition to the git idea, I suggest installing and running http://drupal.org/project/security\_review which may have some suggetsions. Another potential helper is: http://drupal.org/project/paranoia
> 7 votes

# Answer
> "Never touch the modules, so you can update them" There are often situation where you have to patch modules to fix bugs or add features that aren't in the latest stable release. This practice is generally ok as long as you are careful.

Always use version control as it helps you keep track of changes you have made, as well as changes someone else might have sneakily made.

I also recommend including a patch file of the changes in the module directory, which allows you to see at a glance if a module has been modified and what the changes were.

Also commit the patch file to version control. The patch file also makes things easier when updating the module as it can often be reapplied after the update (sometimes if it doesn't apply to the new version you have to manually apply and re-create the patch).

Make sure the patch file name includes the drupal.org issue node id and comment id, so that you can easily check the progress of the issue that the patch addresses, so you can see if the new version of the module already includes the patch or not and you can get a newer version of the patch if there is one.

> Keep all the login in a safe computer / Use a safe computer to work on the FTP

Yes. Also, use SFTP or SSH to connect to the server.

> Search for any security issue before installing a module

This is generally not something you can do. If you have the latest stable release of a module you should have the most secure. There is no way to see security issues for a module that have not been fixed yet (or it would be easier for people to exploit them). The exception to this are modules without a full release, like dev versions and betas, etc. These modules don't go through the same security processes so they can have security issues posted in the public issue queue. However, even in this case if you have the latest version you should have the most secure version.

> Keep a clean copy of the website somewhere

Yes. This comes down to version control again. If you have the code in a version control repository you have a clean version of the code. You should also keep offsite backups of the database and non-version-controlled files. The idea is you can fully restore a site in the case of emergency and hopefully never lose more than 24 hours of data (or less if you run backups more often).

Also, don't rely on general webhost backups. Do your own backups to a different server where possible. I recently had an incident where the hosting provider had a server issue that took down MySQL, corrupting databases on a bunch of servers. The nightly backups then happened after that, so the nightly backups were also corrupted. So the data restored was in some cases a week old.

This kind of thing can happen with any hosting, however in theory should happen less with more high end hosting. In this case if you take your own offsite backups you can avoid troubles.

It is possible for your backups to have problems too but if you have 2 lots of backups in different places you are much safer.

> What kind of attack I've received?

As greggles says, there are so many possibilities that we can't know the answer to this. Your hosting provider may be able to find out though.

> There are other unsure module in my installation?

As mentioned, version control can easily allow you to see what has been hacked. Aside from that, you could download all the same versions of the modules and drupal core and compare them to yours using diff or a similar command. Then you can review all the differences and see if they are your customisations or something a hacker has done.

It could be a long process but it's good to be absolutely sure.

As for potentially dangerous modules, all you can do is use the latest version of all modules, as they will generally be the safest. There are still always more security issues found though so you must keep them up to date. The security team sends out notices about security updates.

You can also check out https://drupal.org/security, which has 3 tabs of security related information for contrib and drupal core.

> What can I do yet?

Here are some things (there are plenty more):

* Make sure you always keep your drupal modules up to date.
* If you are doing custom development make sure to get up to speed with secure coding practices for drupal & PHP and other related web technologies. A good place to start is Writing secure code.
* Keep your server software up to date (if you have control over that).
* Always use secure connections like SFTP to access the server.
* Always use strong passwords and don't reuse passwords.
* Give user 1 a unique username, not "admin" or similar.
* Don't give the user 1 drupal account out to others, if admins need a higher level of access set up a role for them and give them only what they need.
* If there are other user admins use the userprotect module to keep user 1 safe.
* There are a bunch of other modules for better passwords and roles/access control management that might be useful depending on the website.
> 5 votes

# Answer
I'd add: 1) don't use FTP. 2) use version control on the server so you know what code you put there. 3) don't hack core or contributed modules and make sure to subscribe to security updates. 4) ensure you have set your file permissions on your server correctly so that Apache is limited to what files it can write to.
> 4 votes

# Answer
> What kind of attack I've received?

If your server was not exposed, most likely it was some remote injection exploit which worked over a network which exploits the security vulnerability without any prior access to the vulnerable system (e.g. SQL injection, XSS, etc.).

Example scenario:

1. Your hosting provider sends you the message that your site has been blocked, because it found a lot of IP addresses are visiting some particular file (e.g. `/en/printmail/123`).
2. You identified that this may be caused by Print module, so you've to check which version currently you've.
3. This helped you to find the right security advisory, e.g. SA-CONTRIB-2012-057 which says:

* Security risk: Moderately critical
    * Exploitable from: Remote
    * Vulnerability: Cross Site Scripting
4. Then you know what kind of attack you had and you can start from there knowing the risk by knowing what happened and address the problem.

See also: How to remove malicious scripts from admin pages after being hacked?

> There are other unsure module in my installation?

Try to not installing modules which are less popular therefore not tested properly. Especially when they're executing some dynamic code or they've their own custom code instead of using Drupal API properly or using custom SQL queries instead of using proper API and PDO.

> What can I do yet?

Once you've removed malware, you should:

* keep your Drupal core and all modules up-to-date,
* keep up-to-date with Drupal Security Advisories & related news (Twitter),
* keep up-to-date with your system packages (e.g. `apt-get update`),
* make sure your PHP and web server is up-to-date and configured properly,
* make sure your file permissions are correct,

See: What are the recommended directory permissions?,
* monitor Drupal watchdog and system logs for any suspicious behaviour,
* install *Hacked* module to monitor integrity of modules,
* use some security monitoring tool (like Nagios) to monitor your website,
* avoid using Drupal PHP filters/modules and similar (which allows injection of dynamic code),
* never keep PHP code in your database (like in blocks or views),
* disable development modules (like *Devel*),
* keep learning about recent vulnerabilities to be up-to-date with technology,
* and so on.
> 0 votes

---
Tags: 7, security
---


# Question
Title: How to send emails to 20,000 + registered members efficiently?
I have a Drupal 7 site with about 20,000 members. Sometimes I need to email them all at once. Thus far, I have been adding a rules component (Condition: Make sure user has not opted out of emails, Action: Send email, translated as appropriate for each language) and then used VBO and a view to select all the users on the site.

Unfortunately, with such a large number of users, even when VBO is queued to send emails 10 at a time the batch often encounters some error every few thousand users, so I need to find which user was last e-mailed when the batch error occurred and restart the batch manually.

Is there a more robust (i.e., automatic way that will not break and require manual intervention on my part) to email all the user accounts on the site when the number of users is large?

# Answer
> 0 votes
Below is a summary of how you can improve what you already have in place ...

# Part 1 - Use a flag to keep track of the progress

1. Introduce an additional flag to allow "flagging" of some new or updated "entity" (eg "nodes") by all users "*which you need to email all at once*" (as in your question). Let's assume you label that flag as "eMail notification outstanding" (to indicate that something still needs to happen to send that eMail later on).

This of course assumes your eMails are to be triggered by such new or updated entities. But if you don't have such entities (= you have another reason to send such eMails), you could introduce a dedicated content type and use it as a kind of eMail template (with fields up to your own imagination). And each time you have a new eMail to be delivered, just create an appropriate node (of this dedicated content type) for it.
2. Create a rule to flag the newly saved (or updated) content, using the new flag (from step 1) for each of the users you already have in your existing "*a view to select all the users on the site*".
3. Use the Views and the Views bulk operations (VBO) modules to create a VBO list of all flagged nodes (flagged by the new flag in step 1), sorted by flagging date (oldest first), and limit the results to the first X users only (pick a value for X that fits your needs).
4. Create a new Rules Component that "loads the VBO list" (from step 3) and add a loop to that rule to perform these Rules Actions:

* eMail each of the users in that VBO list (you can probably reuse the Rule to "*send an eMail*" that you already have).
    * unflag (using flag from step 1) the node (for the user for which you just produced an eMail). This to indicate that the eMail notification was completed (no longer outstanding).

In that same rule, as the very last Rules Action, add an action to reschedule the execution of the same rule within Y minutes or hours (pick a value for Y that fits your needs).
5. Use the Rules UI to manually trigger the very first execution of that self-rescheduling Rules Component (from step 4.).

Using the above approach, every Y minutes (or hours), Rules will eMail X users "as requested".

# Part 2 - Recovering from an error

Sooner or later, Mr. Murphy will come along again, and it might cause some error again (eg after a few thousand users). If that happens, all that's needed is to repeat Step 5 ... And even if you didn't realize the error at first (only after X hours or days or so), all that's needed is to repeat step 5 as soon as the error got noticed.

# Answer
> -2 votes
You can split the mails and set the cron to send mails to all the users or You can go with 3rd party tool for sending mass mails to all your site users...

---
Tags: 7, rules, emails, views
---


title: Building a contact form from scratch

text:
# Question
Title: Building a contact form from scratch
Is there a way to force Drupal not to base any contact form on the native *Personal contact form* that comes with it, and thus freely creating contact forms from scratch as done with Webform in Drupal 7?

# Answer
Here are 2 possible paths. I used the first one:

## Path 1:

**Stage A:**

Go to Structure \> Contact forms, and there to "Personal contact form".

1. Under "Manage fields" delete any custom fields you might have added.
2. Under "Manage display", make everything as hidden (under both labels && formats).
3. Optional - Under "Manage form display", make everything hidden.

This will totally hide the native personal contact form.

**Stage B:**

Create a new form, from scratch; Add desired fields to it under "Manage fields", and under "Manage form display" && "Manage display" hide all automatic fields taken from "Personal contact form".

Link to the new form from a menu, and that's it.

If you are new to Drupal in general and using Drupal 8, check Youtube for video tutorials on how to create basic contact forms and make sure to use the steps above if you want to build your contact-form from scratch.

## Path 2

It is best to use the native "Personal contact form" and its native fields that are auto-replicated for other secondary forms if you pursue a minimalist approach, and I, as one who pursue such approach would gladly use it if I could have its fields auto-translated to my sites default language, but without the well known bug in the current Drupal 8 branch (8.1.x) yet to be fixed:

Due to the bug, you can't use the management interface in English and forced to have a XYZ language translated management interface - In some cases it's problematic from at least one reason).

Until this bug will be fixed I personally will use the first path, and might change to path B sometime in the future (in any case its a matter of minutes).

## Notes

I suggest creating your block names only as a singular-phrase names, that doesn't contain any non-letter characters.
> 3 votes

# Answer
You always have the option to create a custom module and do it from scratch using the Forms API.

If you can't or don't want to develop your own module and seek a purely UI configurable solution similar to what Webform provides for Drupal 7, two in development modules exists: The port of Webform for Drupal 8 and the eForm module.
> 0 votes

---
Tags: 8, emails
---


# Question
Title: How to open a link of node in custom region?
I create a custom region in sub-theme. I have constructed a map, on which there is a markers when you click on a link (Image 1) description opens on a full page (as on Image 2). How to open a description in the custom region? (example of custom region is on Image 1) Also I need to transition link eg *http://localhost/node/32* to open map (front page) and opens the description in the custom region? Someone had to deal with such a task? How this functionality can be implemented?

Image-1

>

Image-2

>

# Answer
You can create your block programmatically as explained in this post, and then in the block\_view function, add the content of your node as the block's content, for example:

```
$imported_node = node_load($imported_nid);
$block['title'] = $imported_node->title;
$block['content'] = $imported_node->body;

```

You will have to tweak the values to fit your node content, structure you want to output
> 0 votes

---
Tags: 7, navigation
---


title: Add file field with Form API

text:
# Question
Title: Add file field with Form API
I'm writing a block plugin that uses the form API to allow users to edit its settings, and then output them into a template.

I'm currently using

```
<?php

/**
 * @file
 * Contains \Drupal\my_plugins\Plugin\Block\InfoWithSideImage.
 */

namespace Drupal\my_plugins\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * @Block(
 * id = "infowithsideimage",
 * admin_label = @Translation("Info block beside an image")
 * )
 */

class InfoWithSideImage extends BlockBase {
    public function blockForm($form, FormStateInterface $form_state) {
        $form['image'] = array(
            '#type'          => 'file',
            '#title'         => $this->t('Image'),
            '#default_value' => $this->configuration['image_submit'],
        );
        $form['test'] = array(
            '#type' => 'textfield',
            '#title' => $this->t('Test text field'),
            '#default_value' => $this->configuration['test_submit'],
        );
        return $form;
    }
    public function blockSubmit($form, FormStateInterface $form_state) {
        $this->configuration['image_submit'] = $form_state->getValue('image');
        $this->configuration['test_submit'] = $form_state->getValue('test');
    }

    public function build() {
        return array(
            '#theme' => 'infowithsideimage',
            '#image' => $this->configuration['image_submit'],
            '#test' => $this->configuration['test_submit'],
        );
    }
}

```

The text field works fine, but whenever I try to submit with the file field I get the following error:

> A fatal error occurred: Serialization of Symfony\Component\HttpFoundation\File\UploadedFile is not allowed

Is there something I'm missing? Is it possible to use the form API to allow users to upload files?

# Answer
I discovered that the error only occurred when using the in-place panel editor. When adding the block in the panel page editor there were no errors.
> 0 votes

---
Tags: 8, blocks
---


# Question
Title: Why the template_preprocess_field hook is not called for a custom template?
I'm working in a site that has implemented the template\_preprocess\_field() hook. I want to change the content of a field but the code works for all the nodes except for the nodes of a content type that have a custom template (`node--emploi.tpl.php`) It's strange because I have another template for the nodes of the content type named tarif (`node--tarif.tpl.php`) and in this case the hook is called.

Here the piece of code inside the template node--emploi.tpl.php file:

```
<div class="editor">
  <?php
  /* At this point the body's h2 do not know what the nid is, so a quick and dirty replace will set it right. */
  print preg_replace('/NO-NID[a-z0-9]*--/', $nid . '--', check_markup($field_stm_emploi_temoignage_body[0]['value'], $field_stm_emploi_temoignage_body[0]['format']));
 ?>
</div>

```

# Answer
As @Clive says the problem was that the code didn't use the `render()` function for the field output, and in this case the template\_preprocess\_field() hook is not called.

For the moment I have 2 solutions:

1. Use the render() function in the template file (node--emploi.tpl.php) to create the output of the field. In this case the template\_preprocess\_field() hook is called.
2. Use the template\_preprocess\_node() hook and check `$vars['type']` for my content type. In this case the template file remains equal.
> 3 votes

---
Tags: 7, hooks, theming
---


# Question
Title: How do I programmatically populate a field if another one is empty?
I have a CSV feed running and it currently works perfectly. The client now wants to populate a certain field with a sub-string of another field if the first field is empty, on import. I can't see a way to do that with the normal feeds field mapping or tamper.

How can I achieve this?

# Answer
> 2 votes
Create a custom module, in **mymodule.module** use hook\_node\_update

```
function mymodule_node_update($node) {

  if (!isset($node->field_example[LANGUAGE_NONE][0]['value'])) {
  // If field example is not set (is empty), then...

     $new_value = // ...do some stuff to compute a new value for the field.
     $node->field_example2[LANGUAGE_NONE][0]['value'] = $new_value;
     field_attach_update('node', $node);

  }

}

```

---
Tags: 7, feeds
---


# Question
Title: TemporaryStreamWrapper error during installation
In continuation to my previous question https://drupal.stackexchange.com/questions/208245/openatrium-installation-profile-error

I have another problem in the very next step i.e. during Site Configuration.

* Firstly the theme seems to have broken because CSS is not being applied.
* Secondly, I'm getting the error message.

"Warning: file\_put\_contents(temporary://fil3BF3.tmp): failed to open stream: "DrupalTemporaryStreamWrapper::stream\_open" call failed in file\_unmanaged\_save\_data() (line 1936 of \includes\file.inc).

•The file could not be created."

I understand from some other posts that this is due to missing permissions on "**sites/default/files**" folder. But this folder is created on the fly during installation how do we give access to it. In addition, I believe another possible cause can be due to permissions to "**tmp**" folder. Most of the other posts mention changing that path in "Admin -\> configuration" somewhere, but for that OpenAtrium needs to be completely installed. Where can I change the path for "**tmp**" file through file system.

Appreciate a reply.

# Answer
> Where can I change the path for "tmp" file through file system.

You can set the ***tmp*** path by appending the following line in the site ***settings.php***

```
$conf['file_temporary_path'] = '/tmp';

```

In Addition, all item stored in **variable** table in Drupal site's database can be set with `$conf` array in the same way.
> 0 votes

---
Tags: 7, installation
---


# Question
Title: Getting the actual on/off value from a radio button instead of 1/0
I'm trying to store some data from an EntityForm to a txt-file. This can be easily done with an entity wrapper, but when I get the value of the radiobutton (boolean) they selected I always get 1 instead of the value attached to that button (male/female).

This is my code:

```
$wrapper=entity_metadata_wrapper('entityform', $submission);
$wrapper->field_sex->value();  //this gives 1 instead of male

```

# Answer
> 1 votes
Try not to mix up the concept of an input's *value* and its *label*. They're two different things.

The *value* of a boolean field can only be, by definition, 1 or 0. It's a boolean after all. The *label* for the options can be anything.

To load the labels associated with those values, you'll need to load up the field definition:

```
$info = field_info_field('field_sex');
$allowed_values = $info['settings']['allowed_values'];
$label = $allowed_values[$wrapper->field_sex->value()];

```

---
Tags: 7, entities
---


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

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

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

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

# Answer
> Well, as an example, I have a view that shows the latest 4 blog articles. Blog articles is a content type. I'd like to be able to access all the fields of the content type for each node.

You need to add all those fields to your view, then you can use **views-view-fields--\[viewname\]--\[block-1\].html.twig**

and use `{{ fields.title.content }}` or `{{ fields.field_name.content }}` to print the fields on your twig template.
> 1 votes

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

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

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

# Answer
To achieve this create unformatted view. Then create custom template for that view. Give name to that template as  **views-view-fields--viewname--page/block.html.twig** and then create the HTML structure and then simply print the field accordingly and then save the file and don't forget to flush the cache.
To print the field...suppose you want to print the title and image field then do as below {{ fields.title.content}} {{fields.machine\_name\_of\_image\_field.content}}
thats it.

**Note:** To get the machine name of the field, goto the content type and then manage fields, there you will find machine name of those fields. And remember if you have not add field in view in admin panel and adding it in your template file then it will not reflect.
> 1 votes

---
Tags: views, theming, 8
---


# Question
Title: How to get all terms with services module?
I am working on an app (react native) and when i make a request to get the taxonomy terms i don't get all the terms

This is the url i used to get the terms:

http://example.io/api/taxonomy\_term?parameters\[vid\]=2&pagesize=1000

But when I go to the url from my browser i get the full list of terms!

Here is my fetch code:

```
fetch('http://dev-fnyan.pantheonsite.io/api/taxonomy_term?parameters[vid]=3&pagesize=500').then((response) => response.json()).then((response) => {
    let data=[]
    response.map(i =>{
      data.push({label:i.name, value:i.tid, parent:i.parent})
    })
    this.setState({
      categories: data
    })
  }).done();

```

Can anyone suggest where is the problem?

# Answer
> 3 votes
You need to grant permission for `Perform unlimited index queries` at `admin/people/permissions`. Alternatively, you can set this in `settings.php`:

`$conf['services_taxonomy_term_index_page_size'] = 200;`

---
Tags: javascript, services
---


# Question
Title: Entity 'changed' column doesn't change upon save
I have a custom entity called "release". Release has "state" and "building percentage" fields, which values may change during the release process.

In both "setState" and "setPercentage" entity method I explicitly do the following:

```
$this->setChangedTime(time());
$this->save();

```

However, during the process, the "changed" column in the database always remains the same value. Am I missing something? What could be wrong?

**UPDATE:** Running the "setState" and "setPercentage" in a test script separated, the database gets updated.

**UPDATE2:**

I got it. "ChangedItem.php" - line 37, I logged there, and this is where it sets back to the request time value:

```
   // On an existing entity translation, the changed timestamp will only be
      // set to the request time automatically if at least one other field value
      // of the entity has changed. This detection does not run on new entities
      // and will be turned off if the changed timestamp is set manually before
      // save, for example during migrations or by using
      // \Drupal\content_translation\ContentTranslationMetadataWrapperInterface::setChangedTime().

```

**will be turned off if the changed timestamp is set manually before save**

This "promise" of the comment is definitely not working. Any suggestions?

# Answer
> 2 votes
Okey I found the final reason:

ChangedItem.php

```
  $original = $entity->original;
      $langcode = $entity->language()->getId();
      if (!$entity->isNew() && $original->hasTranslation($langcode)) {
        $original_value = $original->getTranslation($langcode)->get($this->getFieldDefinition()->getName())->value;
        if ($this->value == $original_value && $entity->hasTranslationChanges()) {
         $this->value = REQUEST_TIME;
        }
      }

```

**The conclusion:**

In Drupal 8 if you save the same entity TWICE within 1 second (for whatever reason), you won't able to save your own changed time BUT it will be the REQUEST\_TIME instead... wtf? ...

---
Tags: 8, entities
---


# Question
Title: Add placeholder/help text to Views exposed filter?
Title pretty much says it all. I am looking for a way to add placeholder/help text to a Views exposed filter. This would be text that appears in the filter (in this case, search field) before the user enters a value, and then disappears when the filed is clicked or when text is entered into it.

# Answer
You can do this with preprocess functions. Here's a tutorial on doing this for the default search box; you can do views exposed filters in a similar way.

You may also be able to use the Compact Forms module to do this, though I don't know if it is compatible with Views exposed filters.

Also, there's a module for showing helper text below a field: Better Exposed Filters

To set it up, simply enable the module and then navigate to your view edit page.

* Under **Exposed Form**, click **Basic** next to *Exposed form style* and change it to *Better Exposed Filters*.
* Click on **Settings**.
* Scroll to the bottom and click on **Exposed Filter Settings**.
* Click on **Advanced filter options** and you will see the input text in there, then adjust as necessary.

However, this module will not automatically hide the text upon input.
> 10 votes

# Answer
I've been searching for that and could add placeholder with that way:

1. Open your theme's template.php file (if not exist create one).
2. Add the code below to your template.php file:

(Read the notes below the code.)

```
function mmsearchresults_form_alter(&$form, &$form_state, $form_id){
  if($form_id == "views_exposed_form"){
    dsm($form); // print $form array on the top of the page
    if (isset($form['title'])) {
            $form['title']['#attributes'] = array('placeholder' => array(t('Gemeente...')));
    }
  }
}

```

Note 1: If the form\_alter function is already exist, do not add it again, just copy and paste the `if($form_id=...)` part.

Note 2: Change the 'title' whatever element you want to add placeholder.

Note 3: If you want not to display label, you could do this by css (display: none) or by adding `unset($form['title']['#title']);` inside of the code above.
> 7 votes

# Answer
I had the same issue about putting a placeholder on a exposed filter input, that's why I use jQuery code on a "diplay:none;" bloc.

```
<script src="http://code.jquery.com/jquery-latest.min.js"></script>

<script>

    $(function($){
        var elm = $("#id-of-the-input");
        elm.val(elm.attr('name'));
        elm.focus(function(event){
            event.preventDefault();
            if(elm.val() == elm.attr('name')){
                elm.val('');
            }
        });
        elm.focusout(function(event){
            event.preventDefault();
            if(elm.val() == ""){
                elm.val(elm.attr('name'));
            }
        });
    });

    </script>

```
> 1 votes

# Answer
Using a more specific approach with hook\_form\_FORM\_ID\_alter:

```
<?php
/**
 * Implements hook_form_FORM_ID_alter() for views_exposed_form().
*/
function hook_form_views_exposed_form_alter(&$form, &$form_state) {
    $form['form_name']['#attributes']['placeholder'] = t('Placeholder text here');
}

```
> 1 votes

---
Tags: views
---


# Question
Title: How to define custom date format in page.tpl.php?
I would like to add a custom copyright footer to my site e.g. MONTH YEAR. I have set up a »short« date format for English, French and German in admin/config/regional/date-time/locale. Using `<?php print format_date(time(), 'custom', t('F Y')); ?>` in page.tpl.php is working great.

However I would love to go one step further. How do I print the short date format to page.tpl.php instead of adding them to \*.tpl files separately?

# Answer
You are right using the correct API format\_date(). What you need to do is passing correct value to it.

```
<?php print format_date(time(), 'short'); ?>

```

According to the API doc, the function signature is:

```
format_date($timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL)

```

And it explained how you should handle the translation.

> $langcode: (optional) Language code to translate to. Defaults to the language used to display the page.

`$langcode` is handled automatically if you keep it as default value.
> 1 votes

---
Tags: 7
---


# Question
Title: How to unpublish nodes 50 days after they are created by using the Rules module?
I've tried the method described at https://groups.drupal.org/node/240678#comment-782543 , but it is not exactly what I need. So i changed it a little bit :

### Create a ruleset

Name it "Unpublish Content"

In the Settings/Variables:

* Data type = "Node"
* Label = "node"
* Machine name = "node"
* Save

... next screen...Add rule

* Name = "Unpublish Content Rule"
* Save
* Conditions (1):

+ Content is published
    + Data selector = node
    + Save
* Conditions (2):

+ Content is of type = node
    + Value = your-content type
    + Save
* Actions:

+ Unpublish content
    + Data selector = node
    + Save

# Create a rule

* using `/admin/config/workflow/rules`
* Name = "Unpublish Rule"
* React on event = After saving new content
* Save
* Conditions:

+ Content is of type
    + Data selector = node
    + Value = your-content-type
    + Save
* Actions:

+ Schedule component evaluation
    + Component Value = Unpublish Content
    + Data selector = site:current-date \<-- **"This is what I changed, I want the node to be unpublished 50 days after it's creation."**
    + Identifier value = unpublish \[node:nid\] \<-- **removed this.**
    + node Data selector = node
    + Save

But I don't have date field.

I have tried many methods but nothing seems to work, I don't want to use other modules like Auto Expire.

Any suggestions to get this to work?

# Answer
> 2 votes
Have you looked into Rules Scheduler? The process is similar in that you create your rule, create a component that unpublished content, then use Rules Scheduler in the original rule as the action to run the component 50 days after "date published". Here is a video of scheduling nodes to be published after X time that you can follow: http://www.youtube.com/watch?v=OgRKLXRbPX8 .

# Answer
> 2 votes
Use the Rules module together with `Rules Scheduler` (a sub-module of it), as explained in the steps below. These steps use content type = `article`, instead of `your-content-type`.

### Step 1: Create a Rules "Component"

Here is the Rules **Component** to be created (in Rules export format, just import it in your own environment via copy-paste):

```
{ "rules_unpublish_a_node" : {
    "LABEL" : "Unpublish a node",
    "PLUGIN" : "action set",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node" : { "label" : "node", "type" : "node" } },
    "ACTION SET" : [ { "node_unpublish" : { "node" : [ "node" ] } } ]
  }
}

```

### Step 2: Create a "Rule" using the Rules Component

Here is the **Rule** to be created, in Rules export format (just import it in your own environment via copy-paste):

```
{ "rules_unpublish_nodes_after_50_days" : {
    "LABEL" : "Unpublish nodes after 50 days",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_scheduler" ],
    "ON" : { "node_insert" : [] },
    "IF" : [
      { "node_is_of_type" : { "node" : [ "node" ], "type" : { "value" : { "article" : "article" } } } }
    ],
    "DO" : [
      { "schedule" : {
          "component" : "rules_unpublish_a_node",
          "date" : "+50 days",
          "identifier" : "Unpublish node with node ID [node:nid]",
          "param_node" : [ "node" ]
        }
      }
    ]
  }
}

```

Note that the above rule refers to the *Rules Component* from the previous step. It's in Rules export format, just import it in your own environment via copy-paste (after you adapted `article` in it to fit the machine name of your content type).

### Possible refinement

You didn't specify what should happen if at first a node gets created, but as "unpublished" (instead of "published"). And later on such node is updated, and is changed from "unpublished" to "published". Depending on what you'd want to happen in that case, you may have to further refine the Rules Event and/or Rules Condition (eg: add "Content is published").

### Conclusion

* So you only need a (rather basic) **Action Set** (as in in my Step 1).
* You don't need some date field (as in your question), you simply use a relative date like "+50 days".

---
Tags: 7, nodes, rules
---


# Question
Title: How to render the main menu in alphabetical order regardless of menu link weight?
We are using the main menu of Drupal to build out the main navigation of the site. The content creators have access to add a menu link for a node in any level of the main menu and they are also able to use the weight field to set the location of where the menu link will fall under.

We are using a superfish menu block to render our main menu. We are having trouble figuring out how to always alphabetize regardless of what the current user's language is. How would we accomplish this?

Example scenarios:

1. For English content, the main menu will display all links only when the user's locale is English. Additionally all menu links for English should always be alphabetized regardless of the menu link weight.
2. For Japanese content, the main menu will only display Japanese menu links, but also in alphabetical order
3. For German content, the main menu will only display German menu links but also in alphabetical order.

# Answer
I found that if the menu link weight is the same, then the alphabetical order will be applied.
> 1 votes

---
Tags: 7, nodes, navigation
---


# Question
Title: Getting the node id from the node containing an entityform in submit handler
I'm using the module EntityForm to build a form. This EntityForm will be an entity reference field in the content type ShowForm. ShowForm contains the form and some other fields that give some information about what the form will be used for. Once the EntityForm is filled in, they should be redirected to the ShowForm-node that contained it so they can fill it in again (for someone else). There will be different ShowForm-nodes that all have a reference to this EntityForm, but I have to redirect them to the specific ShowForm-node they filled in the form on.

I've added an extra submit button and submit handler that submits the form and redirects them to a ShowForm-node so they can fill it in once more. The problem is that I can't find a way to redirect them to a ShowForm-node without hardcoding the id (so it's only useable for 1 ShowForm-node).

For example:

```
$form_state['redirect']='node/123'

```

where 123 is the nodeid of the node showing the EntityForm. I'd like to be able to get the nodeid dynamically for redirecting instead of manually putting in '123'.

This is my code so far:

```
function extra_inschrijving_form_alter(&$form, &$form_state, $form_id){

    if ($form_id == 'generiek_inschrijvingsformulier__entityform_edit_form'){
        $form['submit2'] = $form['actions']['submit'];
        $form['submit2']['#value']='Inschrijven en ook een broer inschrijven';
        $form['submit2']['#weight']=100;
        $form['submit2']['#submit'][1]='extra_inschrijving_default_wp_submit';
    }
}

function extra_inschrijving_default_wp_submit($form, &$form_state){
       //Do some stuff

      $node_id=???
      $form_state['redirect']='node/' . $node_id;
}

```

Is there a way to get the right value for this $node\_id? Is it possible?

(I was thinking about adding a hidden field to the EntityForm and using rules to set it with the nodeid of ShowForm when a ShowForm-node is created, but I can't seem to acces the EntityForm's fields in rules even when I use "has field"-conditions)

# Answer
> 0 votes
I've solved it like this:

I've added a hidden field to the EntityForm called parentid and set that value with the id of the ShowForm-node when the node is created. This way I can use this parentid to redirect to the correct ShowForm-node when submitting a form.

---
Tags: 7, forms
---


# Question
Title: Append filter info to URL when using AJAX in 'View' module
I am using the Views module and have created a view for a content type. I have added an exposed filter so that the user can filter the list of content based on a custom taxonomy.

I want to use `AJAX` for filtering the content. Before I select `'yes'` under `'use AJAX'` in the `'advanced' tab`, the filter appends the filter selection to the URL such as `/content-type-view?category='selected-category'`. But once I select `AJAX`, I lose the update to the URL.

I want to combine the two, use `AJAX` but also have unique URL's so that I can direct users to pre-filtered instances of the view.

What am I doing wrong?

# Answer
> 3 votes
What you want to do is manipulate the browser's URL even though there are no page reloads, only AJAX requests taking place.

You are actually in need of the HTML5 History API.

And luckily there seems to be a module available, specific to your case:

https://www.drupal.org/project/views\_ajax\_history

Give this a try and good luck!

---
Tags: 7, ajax, views
---


# Question
Title: How to limit users to a create only one instance of a node type?
I know there is Node Limit module, but since it is in alpha stage since a rather long time, I am wondering if there is more elegant way to do so which does not need additional modules?

# Answer
> 6 votes
FWIW I've been using Node Limit on a dev site for a few weeks now, it's had thorough testing and seems to work perfectly. I'm using the 'Node Limit Type' and 'Node Limit User of Role' sub-modules.

If you want to implement it yourself, you can't really look anywhere better than inside the Node Limit module itself. It implements `hook_node_prepare()` to deny access to the node add form if the user has exceeded the maximum nodes, based on various rules.

A very simple custom implementation might look like this:

```
function MYMODULE_node_prepare($node) {
  if (empty($node->nid) && $node->type == 'the_content_type') {
    // Grab the number of nodes of this type the user has already created.
    $args = array(':type' => 'the_content_type', ':uid' => $GLOBALS['user']->uid);
    $node_count = db_query('SELECT COUNT(nid) FROM {node} WHERE type = :type AND uid = :uid', $args)->fetchField();

    // Get the max allowed number of nodes
    $limit = function_to_get_limit();

    // If the user is at/has exceeded the limit, set a message and send the user
    // off somewhere else.
    if ($limit >= $node_count) {
      drupal_set_message(t('Node limit exceeded'));

      drupal_goto('somewhere');
    }
  }
}

```

You could obviously add further checks in there to make sure the user has a certain role, etc. I'd advise having a flick through the code in the Node Limit module to see how the above could be improved upon.

The above is a 'friendly' way to perform the check (i.e. one that doesn't just throw out a 403 page). If you want to be more militant, you could put roughly the same code in a `hook_node_access()` implementation instead:

```
function MYMODULE_node_access($node, $op, $account) {
  if ($op == 'create' && $node->type == 'the_content_type') {
    // Grab the number of nodes of this type the user has already created.
    $args = array(':type' => 'the_content_type', ':uid' => $account->uid);
    $node_count = db_query('SELECT COUNT(nid) FROM {node} WHERE type = :type AND uid = :uid', $args)->fetchField();

    // Get the max allowed number of nodes
    $limit = function_to_get_limit();

    // If the user us at/has exceeded the limit, set a message and send the user
    // off somewhere else.
    if ($limit >= $node_count) {
      return NODE_ACCESS_DENY;
    }

    return NODE_ACCESS_ALLOW;
  }

  return NODE_ACCESS_IGNORE;
}

```

# Answer
> 3 votes
I only wanted users to be able to create a single node of a content type on my site. In my use case, every user needed to have a node (basically using nodes as profiles), so I used the Rules module to automatically create the node and a relation (with the Relation module) to the user upon account validation (though the relation might not be necessary in your case).

Then, I gave users permission to edit their own nodes of the content type, but not create them.

# Answer
> 1 votes
If you want you can study the code of the Only One module to see a simple way to accomplish this.

> The Only One module allows the creation of Only One node per language in the selected content types for this configuration.

```
/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function onlyone_form_node_form_alter(&$form, &$form_state, $form_id) {
  $onlyone_content_types = variable_get('onlyone_node_types');
  // Getting the name of the node type.
  $node_type = $form['type']['#value'];
  // Verifying if the new node should by onlyone.
  if (isset($onlyone_content_types) && in_array($node_type, $onlyone_content_types, TRUE)) {
    $node = $form_state['node'];
    // If we are trying to create a new node.
    if (!isset($node->nid) || isset($node->is_new)) {
      $query = new EntityFieldQuery();
      $query->entityCondition('entity_type', 'node')
        ->entityCondition('bundle', $node_type);
      // The site is multilingual?
      if (drupal_multilingual()) {
        global $language;
        $query->propertyCondition('language', $language->language);
      }
      // Executing the query.
      $result = $query->execute();
      // If we have one node, then redirect to the edit page.
      if (isset($result['node'])) {
        $nid = array_keys($result['node']);
        $nid = $nid[0];
        drupal_goto('node/' . $nid . '/edit');
      }
    }
  }
}

```

Disclosure: I'm the maintainer of the module Only One.

---
Tags: 7, nodes, users
---


# Question
Title: Creating commerce product display in rules with PHP results in error
This problem is to do with the following modules:

* Drupal Commerce
* Rules
* Entity

I have the following code in an "Execute custom PHP code" Rules action. It creates a product display to go with a product (also created by Rules).

The problem is, it does not populate the product reference field (`field_product_reference`) and gives an error.

Code:

```
$product = $contact_details_product;
$display = new stdClass();
$display->type = 'product_display_regular';
node_object_prepare($display);

$display->title  = "Product display";
$display->language = LANGUAGE_NONE;

$display->field_product_reference['und'][0]['product_id'] = $product->product_id;
echo "TYPE: " . gettype($product->product_id);
node_save($display);

```

Where:

* `$contact_details_product` is a variable available in Rules due to the previously created 'product' (as opposed to the display). This product was created in the same rule by a previous action.
* `product_display_regular` is the product display content type.
* `field_product_reference` is the machine name of the product reference field.

Error:

```
Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 178 of /home/test/public_html/includes/entity.inc).

```

Hacking entity.inc to display some values showed that at some point the variable on line 178 gets a null value, so I'm guessing there's a problem with the php code in the rule. Output of gettype and print\_r in entity.inc:

```
TYPE: string
Array ( [0] => 170 )
TYPE: string
Array ( [0] => 170 )
TYPE: NULL
Array ( [0] => )
...

```

That's about all I have right now. Can give more info if needed. Cheers!

# Answer
On further investigation it seems that the product created by Rules (in the previous action) is not assigning a `product_id` in the first place. Therefore there is nothing to assign to the 'product display'.

(I still don't understand why this is happening but rather than change this question completely I will post a new question.)
> 0 votes

# Answer
This work-around will do what you need using Drupal 7 database abstraction layer: This code is from a module I wrote to create product displays from an XML feed:

```
  $title_result = db_query('SELECT title FROM {commerce_product} WHERE product_id = :product_id', array(':product_id' => $prodid))->fetchField();
$node = new stdClass();
$node->title = $title_result;
$node->type = 'product_display';
node_object_prepare($node);

$node->language = LANGUAGE_NONE;
$node->uid = $user->uid;
$node->status = 1; //(1 or 0): published or not
$node->promote = 0; //(1 or 0): promoted to front page
$node->comment = 1; // 0 = comments disabled, 1 = read only, 2 = read/write
$node->field_product['und'][0]['product_id'] = $prodid;
$node = node_submit($node); // Prepare node for saving
node_save($node);
drupal_set_message( "Product Display for " . $prodid . " created.\n");

```

Obviously some variables are in my code that are not accounted for but hopefully it will be clear what I did.
> 0 votes

---
Tags: commerce, rules, entities
---


title: How to insert/update data in database

text:
# Question
Title: How to insert/update data in database
I want to save data in a mysql table database using drupal 7 (costume module), but my question is that depends if the value exists I have to use the UPDATE command and if not INSERT command but I don't know how to write this code with the db api.

# Answer
> 5 votes
Use db\_merge

> In the general sense, a **Merge query is a combination of an Insert query and an Update query**. If a given condition is met, such as a row with a given primary key already existing, then an Update query is run. If not, an Insert query is run.

Thus, **db\_merge** adds it, if it doesn't exist yet. OR updates it, if it already exists.

> ```
> db_merge('example')
>   ->key(array('name' => $name))
>   ->fields(array(
>       'field1' => $value1,
>       'field2' => $value2,
>   ))
>   ->execute();
>
> ```
>
> by: dzutaro, tlyngej, stewart.adam, AndreyMaximov

---
Tags: database
---


# Question
Title: How to implement different landing pages for different countries?
How can I get Drupal 8 to use different landing pages for different countries?

I can create the pages but how do I tell Drupal which page to show for each country? Is geo location the only way, or is there another way?

# Answer
> 2 votes
First thing is, how are you identifying your user's country?

* You could use JS and the geolocation API
* Or you could use the IP of the user and use a database

Id depends on how accurate you need this.
Once you translate the information to an actual country. Then you can decide what to show.

Something to keep in mind is the penalty for this. Instead of showing a different page per country, you might consider showing the same page and maybe via some JS modify an element once you have the location.

---
Tags: 8, i18n-l10n
---


# Question
Title: Force Rebuild of Custom Entity's Task Menu
My module has a custom entity along with custom menu tasks. I would like the tasks shown for a specific entity to be dependent on its properties. Once the properties change I would like the task menu to refresh.

I use custom permissions to determine which menu tabs to show.

I have tried to invalidate the entity's tags after a user changes properties but the task menu does not change (I don't see the permissions being checked again either).

```
\Drupal\Core\Cache\Cache::invalidateTags(array(
        '[my_custom_entity_type]:' . $entity->id()
)

```

If I clear all caches, the entity's menu changes as needed but that is a very expensive operation.

Would love some help.

# Answer
After days of painful searching and reading code, I figured it out on my own. It was super easy once I got it. Since I am using a custom permissions handler to determine if a user should see an entity's task, I added cache tags to the AccessResult object that the custom handler returns:

```
$cache_tags = array('my_custom_entity_type:' . $my_custom_entity->id());

$access_forbidden = AccessResult::forbidden()->addCacheTags($cache_tags);

```

Later when my custom entity changes, I invalidate the tag(s) in the submitForm() function of my custom forms:

```
\Drupal\Core\Cache\Cache::invalidateTags(array('my_custom_entity_type:' . $my_custom_entity->id());

```
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Packing taxonomy fields into one div not from SQL?
I created 2 taxonomy entity-reference fields. One is *Categories* and one is *Tags* and some similar other fields.

In nodes, some of these taxonomy fields appear one above the other.

I want to give some `padding-top` and `padding-bottom` css code, not to each one - but to all together.

Yet, they don't sit inside a wrapping div and wrapping them through the SQL isn't quite comfortable, though I am not sure it's a minimalist/easy to supervise/safe solution.

Do you know a way to bias Drupal 8 to "pack" some of these into a div ? Maybe an intervention in the Twig could do that with some behavior-code?

# Answer
> 1 votes
This is the content of `field.html.twig` in the core theme `classy`:

```
{%
  set classes = [
    'field',
    'field--name-' ~ field_name|clean_class,
    'field--type-' ~ field_type|clean_class,
    'field--label-' ~ label_display,
  ]
%}

{%
  set title_classes = [
    'field__label',
    label_display == 'visually_hidden' ? 'visually-hidden',
  ]
%}

{% if label_hidden %}
  {% if multiple %}
    <div{{ attributes.addClass(classes, 'field__items') }}>
      {% for item in items %}
        <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
      {% endfor %}
    </div>
  {% else %}

```

Each field is packed into a div with its own class `field--name-field-name`. In your case `field--name-field-tags` and `field--name-field-categories`.

## Steps for solution:

1. If you don't use classy as base theme you can put somehting similar in your custom theme or simply copy this twig from the classy theme and change as needed.

core/themes/classy/templates/field/field.html.twig -\> themes/mytheme/templates/
2. Flush all cache.

# Answer
> 1 votes
Go to your theme's templates folder and edit node.html.twig

There, put:

```
<article{{ attributes }}>

  {{ title_prefix }}
  {% if not page %}
    <h2{{ title_attributes }}>
      <a href="{{ url }}" rel="bookmark">{{ label }}</a>
    </h2>
  {% endif %}
  {{ title_suffix }}

  {% if display_submitted %}
    <footer>
      {{ author_picture }}
      <div{{ author_attributes }}>
        {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
        {{ metadata }}
      </div>
    </footer>
  {% endif %}

  <div{{ content_attributes }}>

    {{ content|without('title','body', 'field_categories', 'field_tags', 'field_otherfield') }}

    {{ content.title }}
    {{ content.body }}
    <div class="some-wrapper">
       {{ content.field_categories }}
       {{ content.field_tags }}
    </div>
    {{ content.field_otherfield }}

  </div>

</article>

```

That will print these fields as they presented on this twig file ---\> Packed in a div.

## Notes:

* If you want them without the label use `{{ content.field_name[0] }}`.
* If you want only the label use `{{ content.field_name['#title'] }}`.
* As always with templates, flush the cache to see changes.

---
Tags: theming, 8
---


# Question
Title: setting default language in drupal multilingual module
In my website, I have 2 language English and Marathi. 1st default language is English and I have added some content too. but now my requirement is to set default language as Marathi.

I have gone to admin/config/regional/language setting and done default language as Marathi but not its working.

Please someone help to solve this prob. I want default language on my site as Marathi.

# Answer
Please check these steps as described on this link, How to Change the Default Language of a Drupal Site. You might come to know which step you are missing.
> 0 votes

# Answer
Solved problem. In detection and selection, I have change the order i.e I have put default language on 2nd position and problem solved
> 0 votes

---
Tags: 7, i18n-l10n
---


# Question
Title: How to check in a rule if the data from a field collection has changed?
I want to add a rule (using the Rules module) for printing a message after changing a field in a field collection.

The field collection consists of the following three fields:

1. Reference to Version (type: Entity reference)
2. Related Entities (type: Term reference)
3. Related Properties (type: Term reference)

What I am using for Rule (I have attached a print screen from the rule

EVENT: "Before saving content of type X"

CONDITIONS: Here I am using NOT Data comparison, but it is useless...

ACTION:"Show a message on the site"

**How can I check if the data from a field collection has changed?**

# Answer
> 0 votes
Processing field collections is always fun, and even more fun to do so with the Rules module. My favorite sample to refer to (for actually doing so) is contained in part 1 of my answer to "How to iterate over all field collection items in an eMail body using Rules?".

Have a look at comment #2 of the issue about "Field Collection does not work with Rules' 'node-unchanged' option", which states:

> ... For example:
>
> 1. Create a content type with a field collection that contains an integer field.
> 2. Create an "After updating existing content" rule for that content type.
> 3. Add a "Show a message on the site" action that prints the integer field attached to node:field-collection and node-unchanged:field-collection.
>
> The printed value for node-unchanged is wrong. It shows the changed value.

So far the bad news, read on in comment nr 3 of that same issue, which is like so:

> ***The reason that node-unchanged and node both show the same (new) field collection values is that the node stores a reference to the field collection. The field collection is a separate entity. Changes to it can be caught by the rules events for field collections. The "after updating an existing field collection item" event gives the correct unchanged and new values.***

With this explanation in mind, have a look at this rule (in Rules export format):

```
{ "rules_verify_updates_to_field_collection_items" : {
    "LABEL" : "Verify updates to field collection items",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_conditional", "field_collection" ],
    "ON" : { "field_collection_item_update" : [] },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "field-collection-item" ], "field" : "field_reviewers" } }
    ],
    "DO" : [
      { "LOOP" : {
          "USING" : { "list" : [ "field-collection-item-unchanged:field-reviewers" ] },
          "ITEM" : { "previous_reviewer" : "Previous reviewer" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "NOT list_contains" : {
                      "list" : [ "field-collection-item:field-reviewers" ],
                      "item" : [ "previous-reviewer" ]
                    }
                  },
                  "DO" : [
                    { "drupal_message" : { "message" : "Reviewer [previous-reviewer:name] was removed from the list of reviewers in field collection item with id [field-collection-item:item-id]." } }
                  ]
                }
              ]
            }
          ]
        }
      },
      { "LOOP" : {
          "USING" : { "list" : [ "field-collection-item:field-reviewers" ] },
          "ITEM" : { "current_reviewer" : "Current reviewer" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "NOT list_contains" : {
                      "list" : [ "field-collection-item-unchanged:field-reviewers" ],
                      "item" : [ "current-reviewer" ]
                    }
                  },
                  "DO" : [
                    { "drupal_message" : { "message" : "Reviewer [current-reviewer:name] was added to the list of reviewers in field collection item with id [field-collection-item:item-id]." } }
                  ]
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

```

Some details about the above rule:

* Rules Event: After updating an existing field collection item. Note that this is different from the Rules Event you're using!
* Rules Condition: Entity has field, for a field with machine name `field_reviewers`, which is a multi value entity reference field (to users).
* Rules Actions:
    + The 1st loop (related to `field-collection-item-unchanged:field-reviewers`), will discover all **removed** reviewers.
    + The 2nd loop (related to `field-collection-item:field-reviewers`), will discover all **added** reviewers.

Obviously, for this rule to work you'll also need the Conditional Rules module, though you could also rework the Rules Action to performing Rules Components (in which you add the appropriate Rules Conditions), so that you don't need this extra module (for more details on that, refer to the answer to "What's the alternative to using the Conditional Rules module?").

Here is a demo of this rule (= some Drupal messages shown after I added/removed some user references in 2 field collection items (with id = 5 and 6):

```
Reviewer Hillary.Trump was removed from the list of reviewers in field collection item with id 5.
Reviewer UltraBob was added to the list of reviewers in field collection item with id 5.
Reviewer Donald.Clinton was removed from the list of reviewers in field collection item with id 6.
Reviewer Dries.Buytaert was added to the list of reviewers in field collection item with id 6.
Reviewer Pierre.Vriens was added to the list of reviewers in field collection item with id 6.

```

To finish: you're question may require a slightly different set of Rules Conditions, i.e. since you want to compare some field before the update (= unchanged) versus after the update. But if you're using the same Rules Event and Rule Condition (= Entity has field, for your field collection field), you should be able to perform such comparisons also.

---
Tags: 7, rules, entities
---


title: CKEditor and attributes

text:
# Question
Title: CKEditor and attributes
I wish to enforce a site-wide set of attributes to content produced via CKEditor.

For example, if someone inserts a table, I want the class 'myclass' automatically added as follows:

```
<table class='myclass'>...</table>

```

I want to do this for a large number of tags.

I have tried achieving this by modifying twig templates like table.html.twig, however CK editor content does not appear to apply any template, it only renders the entire post with field.html.twig.

What is the best - or generally accepted- way to accomplish this? I could modify the CKEditor Module directly but that would be modifying core which is not ideal.

This is a drupal 8 site.

# Answer
> 4 votes
You can tackle this problem from both sides, with a ckeditor plugin as @Sssweat suggested and on the drupal side with a filter plugin.

This is an example from core which adds classes to tags. This code looks for the attribute 'data-align', but you can also look for tags:

```
namespace Drupal\filter\Plugin\Filter;
use Drupal\Component\Utility\Html;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
/**
 * Provides a filter to align elements.
 *
 * @Filter(
 *   id = "filter_align",
 *   title = @Translation("Align images"),
 *   description = @Translation("Uses a <code>data-align</code> attribute on <code><img></code> tags to align images."),
 *   type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
 * )
 */
class FilterAlign extends FilterBase {
  /**
   * {@inheritdoc}
   */
  public function process($text, $langcode) {
    $result = new FilterProcessResult($text);
    if (stristr($text, 'data-align') !== FALSE) {
      $dom = Html::load($text);
      $xpath = new \DOMXPath($dom);
      foreach ($xpath->query('//*[@data-align]') as $node) {
        // Read the data-align attribute's value, then delete it.
        $align = $node->getAttribute('data-align');
        $node->removeAttribute('data-align');
        // If one of the allowed alignments, add the corresponding class.
        if (in_array($align, array('left', 'center', 'right'))) {
          $classes = $node->getAttribute('class');
          $classes = (strlen($classes) > 0) ? explode(' ', $classes) : array();
          $classes[] = 'align-' . $align;
          $node->setAttribute('class', implode(' ', $classes));
        }
      }
      $result->setProcessedText(Html::serialize($dom));
    }
    return $result;
  }
}

```

The scaffolding of a custom filter module is very simple. See the tutorial:

https://www.lullabot.com/articles/creating-a-custom-filter-in-drupal-8

---
Tags: 8, wysiwyg
---


# Question
Title: Create content after editing other content-type
I have a certain content-type B with an entity reference to items of content-type A.

I'm trying to programmatically create a content-type B node when a bool field in content-type A is set to `true`, whether during creation of content-type A or update/editing of content-type A.

Something like this story:

> When user creates or edits a `news` content (ie, sets the `push_to_slider` field as `true`), create a `slide` content if it doesn't exist. If the user sets the field as `false`, delete the `slide` content.

I've been exploring how to do this, and I found out about `hook_entity_presave`. So, right now, I'm able to check what was edited in the content-type A form, and if it is being created or updated.

My questions are:

* **How can I find out the ID of the content-type A node?** I need to know it so I can pass it along when I `getStorage('type-B')->create(array)`. This might be available when *editing* a A-type node, but not when *inserting* it, at least not in `hook_entity_presave`. As far as I can tell, I might be doing this in the wrong place as this hook operates **before** the DB insertion, is this correct? As such I think I wouldn't have access to an ID at this point. What could be the alternative?
* Also, **how can I find out if a B-type content already exists referencing the A-type node I'm working with?** I intend to use that to find out if what I need to delete in case the option in the form is set to `false`.

Hope this makes sense. If not, let me know and I'll try to clarify. Any help would be very appreciated.

# Answer
> 1 votes
I'll try to document what I learned during the process of trying to figure out how D8 works (namely, 8.1.x, which is the version I'm working with), in order to find a solution to my problem.

So, the first thing I had to find out was where I had to produce the changes I needed. I though of hook\_entity\_presave but it wasn't the way to go because I would need info on nodes that might not exist at the time that hook would be called. I found out there are 2 hooks used when inserting or updating nodes. As both of my entities are nodes, this is where the magic happens each time you edit or create new content nodes - in my case, both the A and B types mentioned in the question.

Each of these functions has an `$entity` parameter variable with methods available for pretty much everything you might need.

For instance, if you need to know which content-type the `$entity` represents in a given call to these hooks you can simply call its bundle() method:

```
$node_content_type = $entity->bundle();

```

In many cases, the node's value for fields will be available like this:

```
$title_field_value = $entity->title->value;

```

Other times, like this:

```
$custom_field_value = $entity->toArray()['field_custom_field_name'][0]['value'];

```

Particularly, if you need the `id` for a node, you can simply:

```
$node_id = $entity->id();

```

But maybe most importantly, I found out about Drupal 8's entityQuery function, and how to use it. In my scenario, I used it to check for the existence of certain node `id` to programmatically produce some behavior.

This takes me to the node methods I was looking for:

* **Node::load($id)**: when you already have an ID (for instance as a result of the query), and want to load the entire node for some operation on its values;
* **Node::create(array)**: you can *create* a new node with this method by passing it an array of the values you want/need. Needs to be `save()`'d after creation;
* **Node::delete()**: deletes the node. **DOES NOT** need `save()`;
* **Node-\>set(field, value)**: after you `load()` a node, you can use this method to set (ie, update) its values. Also needs `save()` when done.

On a final notice, remember that when using `save()`you will always go through either the `insert` or `update` hooks, if you either create a new node or update it, respectively. Remember this *especially* if you create a new node when updating another one - I did it wrong and got caught in a loop between inserting and updating nodes that generated heaps of repeated content in my D8 install (oops!...).

**DISCLAIMER:** I wrote this answer to my own question because I felt the need to clarify many of these aspects for someone that might have a similar issue. I also +1'd @ssibal's answer because it pointed me to the need of using `entityQuery`. I think D8's documentation is still very sparse/inconsistent and I had to scavenge lots of sources to figure this out. Hope it helps anyone.

# Answer
> 1 votes
**How can I find out the ID of the content-type A node?**

You should use devel module's kint function to get all available methods of an object, and you could easy find out, that it's: $node\_object-\>id();

**how can I find out if a B-type content already exists referencing the A-type node I'm working with?**

You will write a Database service query (not pure sql query), where you will have two important condition:

* the node type must be B
* it's reference field contains the id of the A content.

You will of course have to use table joins. To better understand the schema representation of your content types, I suggest you do use phpmyadmin parallel.

---
Tags: 8, entities, hooks
---


# Question
Title: What does #optional mean for a "details" form element?
The node edit form contains the following form element.

```
  $form['revision_information'] = array(
    '#type' => 'details',
    '#group' => 'advanced',
    '#title' => t('Revision information'),
    // Open by default when "Create new revision" is checked.
    '#open' => $node->isNewRevision(),
    '#attributes' => array(
      'class' => array('node-form-revision-information'),
    ),
    '#attached' => array(
      'library' => array('node/drupal.node'),
    ),
    '#weight' => 20,
    '#optional' => TRUE,
  );

```

What does the `#optional` property mean for it?

I looked at both the `Details` and the `VerticalTabs` classes, but neither of them seems to handle that property.

What does setting `#optional` to `TRUE` do?

# Answer
> 4 votes
This is handled in the render element `Details`. (See the *Details.php* file.)

```
public static function preRenderDetails($element) {
  // Omissis
  // Do not render optional details elements if there are no children.
  if (isset($element['#parents'])) {
    $group = implode('][', $element['#parents']);
    if (!empty($element['#optional']) && !Element::getVisibleChildren($element['#groups'][$group])) {
      $element['#printed'] = TRUE;
    }
  }
  return $element;
}

```

If `#optional` is `TRUE` and there are no visible children, then the element is not rendered.

---
Tags: forms, 8
---


# Question
Title: How to create a folder after clicking on a button?
I got a requirement like this: In the admin page there should be one create folder button, user can create a new folders as per his wish. How can I achieve this programaticaly.
Till now I created a admin page there one button is also coming, but I am not getting how to proceed further.So please give some suggestions, thanks in advance.
Below code I have tried.

```
  $form['create_folder'] = array(
    '#type' => 'submit',
    '#value' => t('Create folder'),
    '#submit' => 'custom_submit',
  );
function custom_submit($form, &$form_state){
  $new_folder = 'public://newfolder/';
  file_prepare_directory($new_folder, FILE_CREATE_DIRECTORY);
}

```

When I click on the submit button I got this warning
`Warning: Invalid argument supplied for foreach() in form_execute_handlers() (line 1507 of C:\xampp\htdocs\drupaltest\includes\form.inc).`

# Answer
> 0 votes
This may help:

```
   $form['folder_name'] = array(
        '#type' => 'textfield',
        '#title' => t('Folder Name'),
    );
    $form['create_folder'] = array(
        '#type' => 'submit',
        '#value' => t('Create folder'),
        '#submit' => array('custom_submit'),
    );

    function custom_submit($form, &$form_state) {
        $new_folder = 'public://' . trim($form_state['values']['folder_name']).'/';
        file_prepare_directory($new_folder, FILE_CREATE_DIRECTORY);
    }

```

Add validation on folder name.

# Answer
> 1 votes
The `#submit` property takes an array of function names rather than a single string:

```
$form['create_folder'] = array(
  '#type' => 'submit',
  '#value' => t('Create folder'),
  '#submit' => array('custom_submit'),
);

```

---
Tags: 7, forms
---


# Question
Title: How to validate dependent fields for a content type?
In one of my content types I have 1 field 'venue' with a drop down option. If I select 'venue' as 'other' from the drop down, some other fields (say 'venue address' and 'venue name') should become required fields and the node should not be saved or updated if those required fields are empty.

This is the screenshot of the rule I created.

This is my rule in Rules export format:

```
{ "rules_schedule_program_venue" : {
    "LABEL" : "Schedule Program venue",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "node_presave--schedule_programs" : { "bundle" : "schedule_programs" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_venue" } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_venue_address" } },
      { "data_is" : {
          "data" : [ "node:field-venue" ],
          "op" : "IN",
          "value" : { "value" : { "9" : "9" } }
        }
      },
      { "data_is_empty" : { "data" : [ "node:field-venue-address" ] } },
      { "node_is_of_type" : {
          "node" : [ "node" ],
          "type" : { "value" : { "schedule_programs" : "schedule_programs" } }
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "address field is required",
          "type" : "error",
          "repeat" : "0"
        }
      }
    ]
  }
}

```

Please let me know what Rules Action I need to add to show an error message without updating or saving node.

I tried adding the *Show a message on site* action, but it is updating or saving the node anyway. I also tried with the *Set an error on the form* action, but in *Data selector* there isn't the *field venue address*.

Any other suggestion using javascript or jquery to achieve this task is also fine.
Can anybody help me in using 'Rules Forms' module in this case?

# Answer
> 1 votes
I'm not aware of a way to get this to work using the Rules module. Because even if you use Rules Action "set a message" (of type = error) the node will still be saved. For more details on this, and/or possible work arounds, refer to my answer to "How to add a confirm dialog to node add and edit forms?".

If you really want to get this to work with Rules, a possible work around for your case might be to also use the Conditional Rules module, so that in your Rules Action you could "add a Rules Condition" (yes!) to check which option got selected for "venue". And if it is NOT "other", then within your Rules Action you set some dummy value (like "n.a."?) for "venue address" and "venue name".

# Plan B

An alternative solution that you may want to experiment with (to see if it works in your case), is the Conditional Fields module. Excerpt from its project page:

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

---
Tags: rules
---


# Question
Title: Youtube API module: Post videos to Youtube
I need to upload videos of my site to Youtube. From Load video to youtube when node save a few modules are introduced that do this.

But I need to do this using an API. I mean I don't want to use the modules interface, I need to have a special interface which is a simple `checkbox` in the node page of a video to post the video, once a user checks the `checkbox`.

The Youtube API module seems to be the appropriate module to do this, But I really have no idea of how to use this module. Using the APIs I can use a simple `.php` file, by calling it via AJAX, then post the video.

How can I do this? Is there any tutorial for Youtube API module?

# Answer
> 1 votes
Create a custom module, in **mymodule.module** use hook\_node\_update

```
function mymodule_node_update($node) {

  if (isset($node->field_checkbox[LANGUAGE_NONE][0]['value'])) {
  // If field checkbox is set (not empty), then...

     // youtube api code goes here.

  }

}

```

> The Youtube API module seems to be the appropriate module to do this, But I really have no idea of how to use this module.

According to the Youtube API module project page:

> This module is an API module, meaning that it **in itself doesn't do anything**

Therefore, all this module does is install libraries that you need in order to interact with the Youtube API, nothing more.

You need to read the Youtube API documentation from https://developers.google.com/youtube/documentation/ and learn how to code for youtube api.

---
Tags: 7, files
---


# Question
Title: Why do Chinese auto path URLs become something else?
I have a Drupal 7 site with i18n on it. There are lots of languages. The problem is that if you save a node that is in Chinese, and you select auto path, then the title that was, for example, /空氣清淨機 will be changed to /kong-qi-qing-jing-ji.

What exactly is this process called? Is it an "English alphabet" version of the Chinese text?

# Answer
> 1 votes
The process you are describing in your question is called ***transliteration***.

The reason for what you see happening in your site, might be because you're using the Transliteration module. Here is a quote from its project page:

> Provides one-way string transliteration (romanization) and cleans file names during upload by replacing unwanted characters.
>
> Generally spoken, it takes Unicode text and tries to represent it in US-ASCII characters (universally displayable, unaccented characters) by attempting to transliterate the pronunciation expressed by the text in some other writing system to Roman letters.

Here is a sample of what this module does for "**file names**":

However, it can also be used to transforms an URL like `mydomain.com/последние-новости-в-Украине-и-мире` in something like `mydomain/poslednie-novosti-v-Ukraine-i-mire`. To do so, you also need to enable the Pathauto module. After that, go to the Pathauto setting page and check "Transliterate prior to creating alias". For more details on that, refer to "D7 Pathauto transliteration". **Attention**: this does not "fix" already created aliases (those need to be deleted and recreated).

**Note**: There is also a tag on drupal.SE (with only 4 questions using it though ...).

---
Tags: 7, i18n-l10n, path-aliases
---