When pasting content from WORD a lot of the markup is being cleared up by using "Force cleanup on standard paste" using TinyMCE and WYSIWYG module. It seems however to leave in the following code:
<p> </p>
Is there any way so that I can filter this out?
The empty p tags were formerly placed to denote a change of line, however drupal wysiwyg automatically adds a non-breaking space tag which thereby fails to display properly and thus be replaced with the character replacement "?"
Working Solution:
$to_filter = array('bloc_1_delta', 'bloc_2_delta', 'bloc_3_delta', 'bloc_4_delta');
if (in_array($vars['block']->delta, $to_filter)) {
$vars['block']->content = str_replace("<p></p>", "<br/>", mb_cοnvert_encoding($vars['block']->content, 'HTML-ENTITIES', 'UTF-8'));
}
Are you sure that it's caused by TinyMCE and WYSIWYG? It can also be the combination of a setting in WYSIWYG (when "Remove linebreaks" is off) and your input filter settings ("Line break converter" is on).
As far as i know does tinymce have a clean code function.
When this one is called it should remove the empty paragraphs.
But you should have to try this...
This happens in almost every js WYSIWYG. Altering the "paste from word" behavior specifically would involve patching or extending the timymce/wysiwyg javascript, but if you don't care where empty <p> tags come from and want to get rid of every one that is submitted, you have some options.
[edited my answer after I had to do this recently again myself]
If you need a lot of html correction/rewriting you probably should look at the HTML Purifier module. It has an advanced option to remove empty and nbsp filled HTML elements, along with correction and xss filtering. But it's slow.
There's the Empty Paragraph Killer module, but it doesn't work for D7 right now so you can skip that.
The most direct solution is to write your own input filter in a custom module. There's an example filter module here you can copy and learn from. Or you can just copy mine:
/* Implements hook_filter_info(). */
function YOURMODULE_filter_info() {
$filters['kill_empty'] = array(
'title' => t('Kill Empty Paragraphs'),
'description' => t('Remove paragraphs that contain only whitespace (including line breaks and \'s) that are often inserted by editors using WYSIWYGs.'),
'process callback' => '_YOURMODULE_kill_empty',
'tips callback' => '_YOURMODULE_kill_empty_tips',
);
return $filters;
}
/* Process callbacks, where the work is done. */
function _YOURMODULE_kill_empty($text, $filter) {
// Remove all <p> tags containing only nbsp's, white space, or nothing.
return preg_replace('/<p[^>]*>( |\s)*<\/p>/', '', $text);
}
/* Tips for the content editor, if you want them. I usually take these out. */
function _YOURMODULE_kill_empty_tips($filter, $format, $long = FALSE) {
if (!$long) {
// This string will be shown in the content add/edit form.
return t('Use one [enter] to create a new paragraph. More than one will be ignored.');
}
else {
// And this one on the "Filter Tips" page.
return t('To maintain consistancy in content display, empty paragraphs inserted by WYSIWYG editors will be removed.');
}
}
Put all of that in a custom module, go to configuration and edit your text formats, and activate the "Kill Empty Paragraphs" filter. That should be it.
Last note is that if you really want them gone, like not-in-the-database, will-never-come-back gone, you should be able to use this filter with the Sanitizable module to remove all of the empty <p>s on submit. The usual warnings about messing with content before it goes into the database apply.
You don't always need the above hacks. as marcvangend mentioned but in plainer english you can change it in settings.
Go to drupal administer
Site configuration
Input formats
configure the input format of your choice
unselect "Line break converter"
A quick and easy way is just to put something like this in your theme's template.php:
<?php
function THEMENAME_preprocess_node(&$vars, $hook) {
$vars['content'] = str_replace('<p> </p>','', $vars['content']);
}
That just does a quick find and replace to replace the empty paragraph with nothing. It's sort of a hack, but it works.
Related
I'm trying to remove the title of a page node on Drupal. I have this page:
And I want it to look like this:
As you can see, I want the title to be removed, but only for taxonomy terms. If I try to erase it using CSS, I erase al page-titles, so I wanted to use this module, that allows administrators to auto-generate node titles and hide it.
I go to structure -> type content -> my type content, and edit it. I activate the module, and I want to auto-generate titles depending on the node category. I think it should look like this, but it doesn't work...
Any ideas why?
EDIT: Sorry, I forgot to say: yes, when I activate the module, use it, and select the category as the auto-generated title, it works. But it doesn't hide the title...
It also launches this mistake:
Use Exclude Node Title module.
https://drupal.org/project/exclude_node_title
Setting for this module:
Click on Module->Exclude node title->configure
Home » Administration » Configuration » Content authoring
Select All nodes from Basic Page
Check Full Content for hide title from all cms page except home page
Check Teaser for hide title from home page.
If you want to remove the title, you should look into overriding the page and node templates.
page.tpl.php and node.tpl.php
All you need to do is click "View Source" on both of those and copy them to your theme folder. From there you can modify both as required.
From what I can gather, you'll want to remove the print $title from your node.tpl.php.
Have the similar issue before, as far as I remember, I just added some if statement to the code:
<?php if (blah-blah-blah): ?>
<h2> <?php echo $title; ?> </h2>
<?php endif; ?>
Hope, it'll give you a clue.
Some other thoughts: you can make an if statement or rewrite it not only in page.tpl.php but create some specific page-node-type.tpl.php file and overwrite only its $title, or you can try to customize page's output via Views/Panels modules as well.
Also, could you please make more clear, what title do you want to remove? Page title or node title? And it should be removed only when you are looking nodes associated with some taxonomy term (in other words, when you are on /taxonomy/term/n page), am I right?
By using the Context module, you can add classes to the body so you can target just the taxonomy pages in CSS.
Using Context module to set body classes
Sorry guys, it was as easy as hide title tag on "manage presentation"...
You are all right on your responses, but they were not exactly what I needed... thanks!
Use Exclude Node Title module.
https://drupal.org/project/exclude_node_title
another nice solution for specific nodes, is to use the standard $title_prefix/suffix vars, which should be implemented by every theme. using the standard class element-invisible in page preprocess ..
like:
/**
* Implements hook_preprocess_page().
*/
function YOUR_THEME_preprocess_page(&$variables) {
if (isset($variables['node']) && $variables['node']->nid == 1) {
$variables['title_prefix'] = array('#markup' => '<div class="element-invisible">');
$variables['title_suffix'] = array('#markup' => '</div>');
}
}
Every page should contain a heading.
You should always maintain a structured hierarchy of headings within any web page. You should never have a blank heading or even hide it with display:none;. Hiding any content which isn’t viewable by your visitors but is by search engines is against Google’s guidelines as your intention is to only manipulate search engine results by including it. Restyle a H1 so it fits into your design is the best option.
If you still have to hide it then a better option would be to either create a template for that node, content type or page and simply not print the heading.
Or if you want to use CSS then use position:absolute so the heading doesn’t use any space where it is located in the page and text-indent:-9999px; so the text is moved off the screen and no longer visible but at least can be read by screen readers and search engines.
This is how I did it, Switch statement
// Get the name of node
$node_name = node_type_get_name($node);
// Then just add the content types you wish to exclude by overwriting the // $title object with an empty string
switch ($node_name) {
case 'Home page':
$title = '' ;
break;
case 'Event':
$title = '';
break;
case 'Offer':
$title = '';
break;
}
For each node preview, I want to have little flag icons at the top representing the available translations. I have seen the language switcher code, but it outputs all the languages all the time. That is annoying because people will click their language and then find that the page is only available in English anyway (I have a site with many articles in a great variety of languages). I have seen this done though. I'm relatively new to Drupal programming. Can anyone give me a pointer?
Thanks!
Figured it out by myself, and noting it here because I know I'm not the only one with this issue.
The template I'm working off is called scaccarium, so I went to /themes/scaccarium/template.php and added the following function:
function scaccarium_preprocess_node(&$vars) {
$node = $vars['node'];
$translationlinks = array();
// Move translation links into separate variable
foreach ($node->links as $key => $value) {
if ($value['attributes']['class'] == 'translation-link') {
$translationlinks[$key] = $value;
// unset($vars['node']->links[$key]);
}
}
$vars['translationlinks'] = theme('links', $translationlinks, array('class' => 'links translationlinks inline'));
}
If your template is called something else, you should obviously go to a different folder and also change the first word of the function name. And if your theme comes with an existing _preprocess_node function, carefully modify it.
Then, I went to my template's node.tpl.php and I added
<?php if ($translationlinks) {
print $translationlinks;
} ?>
next to the title.
Then I had to clear the Drupal cache (even though caching was disabled!) in Performance > Caching in order to get this to work.
Done!
...
To add language links at the top of full nodes, I had to add another "print $translationlinks" at a different place in node.tpl.php as well, as the h3 title thing was just for node previews. Then, to remove the redundant language links at the bottom of full nodes, I tried that unset line that you see commented out in template.php - I found that it had no effect even though another website had recommended it. So what I ended up doing was using CSS for this, adding the following to my template's CSS file:
.node-links .translation-link {
display: none;
}
I hope that my experience will help someone else with the same problem.
How do I hide labels that have empty fields when viewing the actual node of a certain content type?
I'd really appreciate anyone's help, thanks for your time.
Another way you could achieve this is by using a custom template file that would apply to all nodes of that content type.
Make sure that node.tpl.php exists in your sites/all/themes/[mytheme] directory first. This template must exist before other custom templates can be called.
Make a copy of your node.tpl.php and name it node--[contenttype].tpl.php (without the brackets).
If you have the Devel module enabled, you can throw a dpm($content); into the file to find out the name of the field you are trying to hide. Or you could look at the content type itself.
Once you have the name of the field, you can now insert this code before the print render($content); statement:
if (empty($content['my_field'])) {
unset($content['my_field']);
}
Clear the cache, and your field will only appear if there is a value stored.
By default, the labels of empty fields are hidden, maybe there's still a 'non breaking space' or some other leftover in the field?
You have to check the difference between an existing node where the problem occurs and a new node where you don't touch the particular field.
Set unwanted labels display hidden in nl/admin/structure/types/manage/selected_content_type/display
I would like to correct first answer. In node.tpl.php we should check #markup instead of field array:
if (empty($content['field_vac_req'][0]['#markup'])) {
unset($content['field_vac_req']);
}
instead of
if (empty($content['my_field'])) ...
If the content type has a lot of fields looping this worked for me:
foreach($content AS $key => $values) {
if (!empty($content[$key][0]['#markup'])) {
print render($content[$key]);
}
}
I have a node with many CCK fields. I want to hide a field from anonymous user. I found there are roughly two approaches from http://www.lullabot.com/articles/modifying-forms-5-and-6. First, I tried theme_theme() with the code below
function ssaa_theme1(&$existing, $type, $theme, $path) {
return array(
'volunteer_node_form' => array(
'arguments' => array('form' => null),
),
);
}
function ssaa_volunteer_node_form($form) {
$out = '';
if (user_is_anonymous()) {
unset($form['field_active']);
}
$out .= drupal_render($form);
return $out;
}
This simple code worked well as I expected but produced strange result too. Save/Preview buttons are appeared on the top of the form and I couldn't move them to the bottom. At first I suspected drupal_render() function but it didn't do anything about the order. It produced same result when ssaa_volunteer_node_form() function was empty.
So I tried second option which uses hook_form_alter() and succeeded. But I still want to figure out why first approach didn't work properly. I think it's more easy and light way to do what I want to do.
Any ideas?
If you only want to deny this one field to users, it makes sense to form_alter it. Otherwise, I also suggest you use Content Permissions. It will give you the power to toggle such settings for all your fields without needing a text editor.
CCK Field input forms do not accept hook_form_alter() very well. They are inserted into the node edit form late in the cycle, so to speak.
This example demonstrates how disable CCK form elements, it can be adapted to suit your needs.
As you have a very specific need, you might want to look at the new Field Permissions module. It is still in development (and I have not tried it), but it allows you to opt-in individual fields to Content Permissions. This prevents your Permissions screen from getting cluttered and from all new fields defaulting to inaccessible.
I think you can just use the Content Permissions module that comes bundled with CCK to set field-level permissions. Once you enable that module, all of your fields will appear in the Permissions area and you can deny permission to anonymous users there. I think that would be a much easier way to accomplish this.
I ran into the same problem in Drupal 6 recently, and your question is valid.
When I displayed the $form object (from template.php) using Devel's dsm() function, I found that the buttons were somehow showing a weight of 0.0111, a float.
The hook_theme() and then hook_form() in template.php seem to be behaving wrong.
Using hook_form I made no changes to the $form object, and returning drupal_render($form) the Save/Preview buttons were at the top.
To anyone that needs to use these hooks, you must ALSO create a form_alter where you set the weight of the buttons. This counteracts the bug and gets your buttons to the bottom again.
$form['buttons']['#weight'] = 100;
Note: I could not set the weight in my hook_form() code, it had to be in a form_alter
When you create a new content type in Drupal using the Content Creation Kit, you automatically get Title and Body fields in the generated form. Is there a way to remove them?
If you're not a developer (or you want to shortcut the development process), another possible solution is to utilize the auto_nodetitle module. Auto nodetitle will let you create rules for generating the title of the node. These can be programmatic rules, tokens that are replaced, or simply static text. Worth a look if nothing else.
To remove the body edit the type, expand "Submission form settings" and put in blank for body field label. For title you can rename it to another text field. If you really have no need for any text fields you can create a custom module, say called foo, and create function foo_form_alter() which replaces $form['title'] with a #value when $form['type']['#value'] is your node type.
No need to install anything:
when editing the content type, press "Edit"
(on the menu of Edit | Manage fields | Display fields )
click on the Submission form settings
on the Body field label:
Leave it blank, it would remove the Body field.
If you're not a developer (or you want
to shortcut the development process),
another possible solution is to
utilize the auto_nodetitle module.
Auto nodetitle will let you create
rules for generating the title of the
node. These can be programmatic rules,
tokens that are replaced, or simply
static text. Worth a look if nothing
else.
And to add on to William OConnor's solution...
The module is poorly documented unfortunately. It's really only effective if you use PHP with it in my opinion. Check off the "Evaluate PHP in Pattern" and type into the "Pattern for the title" field something like:
<?php echo $node->field_staff_email[0]['email']; ?>
or:
<?php echo $node->field_staff_name[0]['value'] . '-' . gmdate('YmdHis'); ?>
...where I had a field with an internal name of "field_staff_email" and was using the CCK Email module -- thus the 'email' type was used. Or, I had a field with an internal name of "field_staff_name" and was just an ordinary text field -- thus the 'value' type was used. The gmdate() call on the end is to ensure uniqueness because you may have two or more staff members named the same thing.
The way I discovered all this was by first experimenting with:
<?php print_r($node); ?>
...which of course gave crazy results, but at least I was able to parse the output and figure out how to use the $node object properly here.
Just note if you use either of these PHP routines, then you end up with the Content list in Drupal Admin showing entries exactly as you coded the PHP. This is why I didn't just use gmdate() alone because then it might be hard to find my record for editing.
Note also you might be able to use Base-36 conversion on gmdate() in order to reduce the size of the output because gmdate('YmdHis') is fairly long.
The initial answers are all good. Just as another idea for the title part... how about creating a custom template file for the cck node type. You would copy node.tpl.php to node-TYPE.tpl.php, and then edit the new file and remove where the title is rendered. (Dont forget to clear your cache).
Doing it this way means that every node still has a title, so for content management you aren't left with blank titles or anything like that.
HTH!