Placing block inside a node (positioning block between specific elements in node's content) - drupal

Basically I created a webform and enabled it as a block, now I want to put that block inside a specific node. I can do that by placing it in a 'content' region and defining the specific node BUT it displays at the end of the content. Now how can I move it between specific elements inside the content?
The node is using a page-type....tpl.php which is used by 5 other nodes as well so I cannot change the code.
To visualize it looks like:
[ content ]
-description text-
-list of videos-
[ end of content ]
and I need to put my webform between the text and the video list. Is there a way?

There are many roads you could take, but since you said you're considering the template file: Why not use a node-specific template, since page is a node type?
Say you're on node/123, then you could use a template named node--123.tpl.php
(see Drupal 7 Template (Theme Hook) Suggestions) and embed your block right there.
Alternatively, you could provide a reusable token in a custom module via hook_token_info and combine it with the commonly used token_filter module. But that might be over the top, if it's just one node you need to touch.

For Drupal 7 a bit of a hacky way to display the contents of a block in content would be to enable the PHP Filter module. Then edit your node and switch to the PHP code Text format and add this code
<?php
$block = module_invoke('block', 'block_view', '1');
print render($block['content']);
?>
where '1' is the block id found in the URL when you edit the block and be sure to include the PHP tags.
Also see this page https://www.drupal.org/node/26502 for more information on placing blocks.

You can use the EVA module to add the webforms in the node as a field.
You basically create a view and choose the "eva field" option then you make sure that this view selects only the webforms you want to have and relates it to the node (the EVA module documentation has much better examples than I can provide).
After you have added it as a field you can place it anywhere in the node.
There is also the Block reference module that could help you.

Related

Override item-list.html.twig & time.html.twig inside a view

I've created a view that outputs a <ul> with a <time> element in each <li>. I need to convert the HTML list to a select.
So I did 2 things:
Copied item-list.html.twig and changed <ul> to a <select>
Copied time.html.twig and changed <time> to <option>
Although this works I need those 2 templates to be scoped to my view named: 'vcon-selection-table'. I tried many things but nothing works:
views-view-table--vcon-selection-table--item-list.html
views-view-table--vcon-selection-table-item-list.html
views-view-table--vcon-selection-table.html--dataset-item-list
So the question is: What template name should I use to override the templates item-list.html.twig and time.html.twig inside my view?
Is the purpose of that view to only provide that <select> element and <option> elements? Then this really isn't the way to go. Don't build a form or form elements with Views.
You'd better provide a custom form or a custom item_list in a custom block. The block then can be placed where ever you need it. There are plenty of tutorials out there. Maybe take the following as a starting point: https://valuebound.com/resources/blog/creating-a-custom-form-in-a-block-in-two-steps-in-Drupal-8
Otherwise, if you really want to continue your road I think you have to simply preprocess the list and time fields to switch to a different template according your desired conditions. I strongly guess there is no option that a custom template for a field from a node in a view will automatically be taken into account by naming patterns. You have to add that template suggestion manually first.
Snippet to be placed in MYMODULE.module file or MYTHEME.theme file.
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function MYMODULE/MYTHEME_theme_suggestions_item_list_alter(array &$suggestions, array $variables) {
// Use \Drupal::routeMatch() to get the current view ID or some other indicator.
// Sample: Get the current view ID.
$view_id = \Drupal::routeMatch()->getRouteObject()->getDefault('view_id');
// Install Devel, Kint module, then uncomment the following line and flush caches to inspect the outcome.
// ksm($view_id);
// Add the template suggestion.
// Add your template now under /templates/item-list--VIEWID.html.twig
if (!empty($view_id)) {
$suggestions[] = 'item_list__' . $view_id;
}
}
Downside of this approach is that this would trigger all item_lists that live on that exact page/view to take this template. You could fine-grain your templating much better with a custom module and a custom item_list and/or form.
Alternatively you can also move the logic to the date field and a custom view mode and an extra template for that. Then at least it stays where it belongs to.
To enable Twig debugging and getting the built-in template suggestions printed as HTML comments follow this article: https://www.drupal.org/docs/8/theming/twig/debugging-twig-templates

Drupal , how to render block in 'content' of a node?

I have a common content in few pages. And I want include the content in 'content' of a node.
What I thought is use block, but I don't know how to use block in 'content' of a node. There is still some other different "div" wrapping the block, and I can't write the block in template file.
What should I do? Thanks!
I would avoid rendering a block directly within the content of a page.
Instead make a new region directly above or below the content (depending on where you want your block to appear) and then put then block in the new region.
It is also possible to render your block directly in the template file using
$block = module_invoke('modulename', 'block_view', 'block_name');
print render($block);
This post discusses the merits of both methods: http://drupal.org/node/345361

Add HTML to node title in Drupal module, not in theme layer

I want to add some functionality to my Drupal 6 module: I want to insert an image next to certain node titles (it involves a span and an img tag). I thought I could do this by just implementing mymodule_preprocess_node() and modifying the title. However, Drupal strips out all tags to avoid XSS attacks.
I've seen many solutions that involve the theme layer (most commonly http://drupal.org/node/28537), but I want to do this in my module, not in the theme. I don't want to modify any .tpl.php files or template.php. Can anyone give me tips on how to do this?
You mention that you've tried preprocess_node(), and are correct that, if you are storing the img tag as part of the node title, Drupal will indeed strip that out, as it runs $node->title through check_plain in template_preprocess_node().
My suggestion would be to store the actual image as an image field (using some combination of the imagefield module and imagecache for sizing), set the display of that field to be hidden on the CCK display tab for the given content type, and then attach the image to be part of the $title variable in your module's preprocess function. This solution would also allow you to display that image next to the title in any views you may need to create.
By 'certain node titles' - do you mean all nodes titles from certain node types?
If so, you can likely style the node using only CSS. By default all nodes will have a class that corresponds to the node type. Using CSS background images, you can add an image to the node title.
Your module can call drupal_add_css and add in any required CSS into the page. This way, it is theme independent.
I think the easier way is with javascript / Jquery.
You create a Jquery script which is called only in certain types of nodes and pass the number of views from drupal to the jscript.
You can call drupal_add_js() inside your module_preprocess_node and pass a variable which contains the number of views or the image link to the script. Something like this:
<?php
drupal_add_js("var mymodule_imagelink = " . drupal_to_js($imagelink) . ";", 'inline');
drupal_add_js("my_js_file.js");
?>
then in my_js_file.js just change the text. There are several ways to acomplish this. For instance, you can do a search in the document and change the title to something else or you can use a determined ID, etc...
Find text string using jQuery?
http://api.jquery.com/replaceWith/

Create an Iframe from a Drupal Website

I have a drupal website. I want to generate an Iframe with content from my drupal site, that other sites can embed.
How I think this can be achieved:
Method 1: Create a php script that is autonomous from the drupal engine.
Import the configuration file and hence gain access to the database. Generate the content as a standalone webpage. Distribute the url of this script as the iframe's source url.
Problems: cannot provide drupal functionality within the iframe such as interaction with logged in user.
Method 2: Create the iframe from within drupal.
Create a new module that defines a menu entry using hoom_menu (the url for the iframe). Define the content of the iframe from the callback function of the menu entry. Then Somehow assign a custom page.tpl.php theme for the desired iframe url so that only the content of the iframe is rendered without all the other page elements (blocks, menus, footer, etc.).
Any comments especially for method 2 will be greatly appreciated! :)
I have done exactly this, just this week!
I created a custom module that outputs only the content that I want (using hook_menu()). Then I created a page template (page-mycustommodule.tpl.php) that only has
<?php print $content; ?>
within the <body> tags.
That was basically all. To find out the name that your page template needs to have, use the devel and theme_devel modules, then just click on your page and it will tell you which templates it looked for.
One thing to look out for: any links in the iframe will only change the contents OF THAT FRAME, so when your module creates links, use the proper target to make the parent page jump to the new URL:
l('link text',
'node/' . $mynode->nid,
array('attributes' => array('target' => '_parent')));
I found the answer by Graham very useful. Unfortunately I don't have enough reputation on this site to add a comment so I will have to put my comment in an answer.
5 years on, the information has changed slightly:
The module theme_devel now seems to be called devel_themer instead.
In D7, the template naming pattern is slightly different with 2
hyphens: page--[front|internal/path].tpl.php (see docs)
D7 templates are slightly different based on render arrays, so the template will need to be something like print render($page['content']);
method 3
you can use this module https://www.drupal.org/project/entity_iframe that allows you to create IFRAME READY webpages
install it and go to the display settings of you content type that you want to use as iframe content admin/structure/types/manage/CONTENTTYPE/display
choose the IFRAME view mode and choose the fields you would like to be shown
and then use url like this domain.com/entity_iframe/node/NID and you will have a display with no extra headers footers etc ...
By default a sample EMBED/IFRAME code is provided to the admin under each node the settings
<iframe width="100%" height="300" src="domain.com/entity_iframe/node/96" frameborder="0" class="entity_iframe entity_iframe_node" id="entity_iframe_node_96" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true"></iframe>
The settings in admin/config/system/entity_iframe control some of the details of the embed code
For complete control of the theme used you can use in combination with https://www.drupal.org/project/entity_iframe_theme
What do you exactly need to iframe?
A node? A block? Should it be static or dynamic?
You can simply create a node with a php filter and generate the iframe output.
Then you can put this output between <pre> tags to display it as code that users can copy/paste in their site.

Conditional link to node within views?

I have two content types, book and chapter. Each chapter node contains a node reference of the book to which it belongs. I have created a view which displays the title of each chapter for a given book. Within the view, the title field has been configured to link to its node.
All works well. I am now interested in updating the view to not display a link to a chapter's node when the chapter's body is empty. Thus this view would display a list of chapter titles for a book and link only to those chapters that have a body.
Can this be accomplished using out of the box Views functionality? If not, how would something like this be accomplished?
Thanks.
I'd use the Views Custom Field module to implement your custom logic. It allows you to grab the data fetched by Views and manipulate it at will with PHP. Very handy.
I'm answering my own question because my response to ceejayoz is poorly formatted.
What I did to accomplish this was to first download and enable views_customfield. Second, I placed Title and Body fields within the view, both excluded from display. Third, within a Customfield: PHP code field I placed the following code:
<?php
if (strlen(trim($data->node_revisions_body)) == 0) {
return $data->node_title;
} else {
return l($data->node_title, drupal_get_path_alias('node/' . $data->nid));
}
?>
There's also this clever workaround which allows you to achieve this very easily:
Add 2 title fields one with link and one with no link, and make both
them exclude from display.
Add body field,
In No result behavior put title with no link replacement token to
it.
In Rewrite results behavior put title with link replacement token to
it.
Tick hide if empty.
Source

Resources