Duplicate ID 'new' in forums breaks XHTML validation (patch attached, just needs reroll)

Damien Tournoud - March 17, 2009 - 20:03
Project:Drupal
Version:7.x-dev
Component:forum.module
Category:bug report
Priority:normal
Assigned:brianV
Status:reviewed & tested by the community
Issue tags:Novice, XHTML, XHTML validation
Description

Reported by #402254: How do we do on XHTML validation?, something is outputting duplicate 'new' IDs in forum listing:

GET http://dev.local/Drupal/Core7/forum/2 returned 200 (9.22 KB).
DOMDocument::loadHTML(): ID new already defined in Entity, line: 96
DOMDocument::loadHTML(): ID new already defined in Entity, line: 108
DOMDocument::loadHTML(): ID new already defined in Entity, line: 120
DOMDocument::loadHTML(): ID new already defined in Entity, line: 132

#1

Dave Reid - March 17, 2009 - 20:16

Let's tag all these with 'XHTML validation'

#2

karschsp - March 18, 2009 - 17:36
Issue tags:+Novice

tagging this for the novice queue. It looks like the problem is in forum-icon.tpl.php.

<?php if ($new_posts): ?>
  <a id="new">
<?php endif; ?>

#3

wretched sinner... - March 19, 2009 - 00:06

#4

brianV - March 19, 2009 - 02:48

Patch attached.

Changed

<a id="new">

to:

<a class="new-posts">

The class name was changed to 'new-posts' since the 'new' class is already used in Garland for the 'new' indicators on comments not yet seen by the users.

.new {
  color: #ffae00;
  font-size: 0.92em;
  font-weight: bold;
  float: right; /* LTR */
}

From Garland's comment.tpl.php:

<?php if ($comment->new) : ?>
    <span class="new"><?php print drupal_ucfirst($new) ?></span>
<?php endif; ?>

I don't think this class name change affects any other theming in core.

AttachmentSizeStatusTest resultOperations
forum-fix-new-id.patch943 bytesIdleFailed: Failed to run tests.View details | Re-test

#5

brianV - March 19, 2009 - 02:49
Status:active» needs review

#6

Damien Tournoud - March 19, 2009 - 22:44

I'm wondering: do we need the first of those links to be tagged with id="new", in order to be a target for #new URL arguments?

#7

brianV - March 19, 2009 - 23:48

I hadn't thought of that. The module uses the first 'id="new"' as the anchor the browser jumps to.

Since the 'name' attribute is deprecated in XHTML, we need to use an 'id' to jump to with that link.

This means we will need to write code to determine which thread is the first unread thread, and create a link before it to act as the target.

Looking into it further!

#8

brianV - March 20, 2009 - 03:11
Assigned to:Anonymous» brianV
Status:needs review» needs work

Just assigning to me, and changing to 'needs work'. I have a pretty good patch on the go that should fix this issue properly. It's just a little more involved than I expected.

#9

brianV - March 20, 2009 - 03:47
Status:needs work» needs review

This new patch adds <a id="new"></a> to only the first new topic in the topic list.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids.patch4.73 KBIdleFailed: Failed to apply patch.View details | Re-test

#10

Dries - March 20, 2009 - 08:02

Or instead of generating id="new", and jumping to that with "#new", we could just link to the proper comment ID?

#11

brianV - March 20, 2009 - 13:35

Dries,

I suspect you may be thinking of the page displaying a given forum topic along with it's replies. In that context, your suggestion makes sense, but it is an issue for comment.module.

(off-topic)
Just to point out a small problem: with the existing approach, the comment.module only has to calculate the most recent comment when the user visits a node containing new comments. In the usage you suggest, the most recent comment would have to be calculated for every node displayed in forum or node listings in order to generate the correct 'new' link containing the comment id to the latest comment, regardless of whether or not the user actually visits the node. This would be somewhat less efficient from a performance standpoint.
(/offtopic)

That aside, this issue is looking at the forum topic list, which shows a table or forum topics, the number of replies, who created it, and who made the last post.

N.B. The handling in the patch I've written is consistent with that used by comment.module in the same situation. comment.module also places <a id="new" /> in the first unread comment in the list of comments.

#12

Damien Tournoud - March 20, 2009 - 15:26
Status:needs review» needs work

Nice!

Some remarks:

1. $is_first_new_topic should be a boolean. I know that $sticky is not, but this one comes from the DB

2.

<?php
+    // make sure only one topic is indicated as the first new topic
+    $topic->is_first_new_topic = 0;
+    if ((
$topic->new != 0) && ($num_new_topics == 0)) {
+     
$topic->is_first_new_topic = 1;
+     
$num_new_topics++;
+    }
?>

Apparently, we don't need to count the new topics, but only to know if we are on the first new topic.

#13

brianV - March 20, 2009 - 15:55

Ok, I will make another pass at it with these comments in mind.

#14

brianV - March 20, 2009 - 16:10
Status:needs work» needs review

New version rolled.

  1. $is_new_topic is now a boolean.
  2. $num_new_topics renamed to $was_first_new_found and made into boolean to better reflect usage.

Relevant code section:

<?php
// make sure only one topic is indicated as the first new topic
$topic->is_first_new_topic = false;
if ((
$topic->new != 0) && (!$was_first_new_found)) {
 
$topic->is_first_new_topic = true;
 
$was_first_new_found = true;
}
?>

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev2.patch4.42 KBIdleFailed: Failed to apply patch.View details | Re-test

#15

catch - March 21, 2009 - 12:18

Dries, being able to link to the correct comment ID instead of #new is the subject of #26966: Fix comment links when paging is used. - there aren't any nice ways to do this with the current state of comment module.

Couple of code style issues with this patch:

+  $was_first_new_found = false;

All the booleans need to be upper case - TRUE/FALSE.

+    // make sure only one topic is indicated as the first new topic

This should start with a capital letter and end with a full stop.

Otherwise looks great.

#16

brianV - March 21, 2009 - 15:28

Oops!

New patch, with coding style fixes recommended above.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev3.patch4.49 KBIdleFailed: Failed to install HEAD.View details | Re-test

#17

System Message - April 4, 2009 - 01:00
Status:needs review» needs work

The last submitted patch failed testing.

#18

brianV - April 22, 2009 - 15:18
Status:needs work» needs review

Re-upping patch with a new name to be retested. Patch applied cleanly against head here, so I have no idea why the testbot failed.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev4.patch4.49 KBIdleFailed: Failed to apply patch.View details | Re-test

#19

dmitrig01 - April 26, 2009 - 00:27
Status:needs review» needs work

How about

<?php
$topic
->first_new_topic
?>
without the is_ just like sticky doesnt have is_ and similarly remove was_

#20

brianV - April 27, 2009 - 15:38

dmitri,

it's a pretty common convention to prefix a boolean with is_ to hint at the type by the name.

If I had to judge by the name alone, I would assume 'first_new_topic' contained the nid of the first new topic, or something similar. 'is_first_new_topic' automatically implies that we are dealing with a boolean.

On the other hand, this convention isn't followed to strictly within Drupal core.

I agree 'was_first_new_found' is pretty nasty.

#21

brianV - June 9, 2009 - 04:45
Status:needs work» needs review

New revision.

I renamed $was_first_new_found to $first_new_found. However, I've left $is_first_new_topic alone for the reasons stated above.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev5.patch4.38 KBIdleFailed: 11624 passes, 0 fails, 5 exceptionsView details | Re-test

#22

System Message - June 9, 2009 - 05:00
Status:needs review» needs work

The last submitted patch failed testing.

#23

brianV - June 10, 2009 - 13:42
Status:needs work» needs review

I accidentally removed a line I didn't intend to in the last patch, causing it to fail some tests.

New patch attached, hopefully the final one for this issue.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev6.patch4.42 KBIdleFailed: Failed to install HEAD.View details | Re-test

#24

catch - June 10, 2009 - 16:36

$is_first_new_topic should probably just be $first_new_topic or $first_new

This bit reads a bit awkwardly to me:

+    $topic->is_first_new_topic = FALSE;
+    if (($topic->new != 0) && (!$first_new_found)) {
+      $topic->is_first_new_topic = TRUE;
+      $first_new_found = TRUE;
+    }

Could we do something like

+    if (($topic->new != 0)) {
+      $topic->first_new = !$first_new_found;
+      $first_new_found = TRUE;
+    }

(not tested)

#25

brianV - June 10, 2009 - 19:29

New version posted.

I renamed $is_first_new_topic to $new_topic.

I've changed the one hunk to closer match what is posted in #6:

+    // Make sure only one topic is indicated as the first new topic.
+    if (($topic->new != 0) && (!$first_new_found)) {
+      $topic->first_new = !$first_new_found;
+      $first_new_found = TRUE;
+    }

Please note that the code above is only executed once, due to checking $first_new_found. If that is omitted (as in #6), the loop is executed for every 'new' comment in the listing, which could be as many as 50 times.

Hopefully, this is the last patch for this issue.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev7.patch4.3 KBIdleFailed: 11089 passes, 0 fails, 22 exceptionsView details | Re-test

#26

brianV - June 10, 2009 - 19:53

After chatting with catch in IRC, I present....

!!!!!REVISION 8!!!!!

Certified 100% bug, BPA and MSG free. This product was not tested on animals.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev8.patch4.35 KBIdleFailed: Failed to install HEAD.View details | Re-test

#27

catch - June 10, 2009 - 20:04

Looks good. I was going to suggest we write a test for this, but really that should be done when #355185: Add XHTML validation to simpletest gets in. Waiting on the test bot.

#28

catch - June 11, 2009 - 09:41

Spotted one more thing - we use if / endif in template files rather than braces, sorry all these came one by one. Re-rolled with just that one change, this should be ready to go.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids.patch3.2 KBIdleFailed: Failed to apply patch.View details | Re-test

#29

Damien Tournoud - June 11, 2009 - 09:49
Status:needs review» reviewed & tested by the community

Nice, more step on the road to generating valid XHTML ;)

Let's get this in.

#30

brianV - June 11, 2009 - 13:09

Re: if / endif in template files..

I wasn't aware of that. Marking down in my book of 'odd little things about Drupal module coding'

#32

System Message - June 19, 2009 - 09:30
Status:reviewed & tested by the community» needs work

The last submitted patch failed testing.

#33

brianV - July 21, 2009 - 01:32

Just bumping this issue - needs to be rerolled. If someone gets to it before I do, good. Otherwise, I will get to it sooner or later.

#34

tylor - July 25, 2009 - 04:11
Status:needs work» needs review

Re-roll of patch from #28.

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev10.patch3.19 KBIdleFailed: Failed to install HEAD.View details | Re-test

#35

brianV - July 25, 2009 - 16:26
Status:needs review» reviewed & tested by the community

Tests pass, looks good

#36

System Message - August 1, 2009 - 07:00
Status:reviewed & tested by the community» needs work

The last submitted patch failed testing.

#37

brianV - September 16, 2009 - 14:24
Title:Duplicate ID 'new' in forums» Duplicate ID 'new' in forums breaks XHTML validation (patch attached, just needs reroll)
Issue tags:+XHTML

Just bumping again. Needs a reroll, but I don't have time to tacke it.

#38

swentel - September 19, 2009 - 13:34
Status:needs work» needs review

Reroll

AttachmentSizeStatusTest resultOperations
forum-fix-duplicate-ids-rev11.patch3.4 KBIdleFailed: Failed to apply patch.View details | Re-test

#39

alexanderpas - September 19, 2009 - 13:42

+++ modules/forum/forum-icon.tpl.php 19 Sep 2009 13:32:36 -0000
@@ -9,17 +9,16 @@
+  <a id="new"></a>

not that happy about this, shoudn't it be <a id="new" />

This review is powered by Dreditor.

#40

brianV - September 19, 2009 - 22:46
Status:needs review» reviewed & tested by the community

Looks good to me. Personally, I don't think it's worth a reroll to compress it down to <a id="new" />

#41

alexanderpas - September 20, 2009 - 16:48
Status:reviewed & tested by the community» needs review

added my own suggestion from #39

AttachmentSizeStatusTest resultOperations
forum_duplicate_id-405238-41.patch3.58 KBIdleFailed: Failed to apply patch.View details | Re-test

#42

brianV - September 21, 2009 - 12:39
Status:needs review» reviewed & tested by the community

#43

System Message - October 8, 2009 - 21:10
Status:reviewed & tested by the community» needs work

The last submitted patch failed testing.

#44

brianV - December 4, 2009 - 15:58
Status:needs work» needs review

Rerolled once again. Setting to CNR so the testbot will look at it, but this has really been RTBC since early June.

AttachmentSizeStatusTest resultOperations
405238-forum_duplicate_id-rev13.patch3.39 KBIdleFailed on MySQL 5.0 ISAM, with: 15,578 pass(es), 0 fail(s), and 26 exception(es).View details | Re-test

#45

System Message - December 4, 2009 - 16:12
Status:needs review» needs work

The last submitted patch failed testing.

#46

brianV - December 4, 2009 - 16:18
Status:needs work» needs review

oops.

AttachmentSizeStatusTest resultOperations
405238-forum_duplicate_id-rev14.patch3.46 KBIdlePassed on all environments.View details | Re-test

#47

brianV - December 4, 2009 - 17:01
Status:needs review» reviewed & tested by the community

Since this is just a reroll of a patch that has been RTBC since June, I am putting back to RTBC.

#48

Dries - December 5, 2009 - 14:40

It would be great to see a screenshot of how this changes the behavior. I'm trying to understand how important this feature is (vs removing it).

#49

sun - December 8, 2009 - 04:44
Status:reviewed & tested by the community» needs work

This is absolutely required for #653940: Clean-up: Tests do not report all errors.

+++ modules/forum/forum-icon.tpl.php 4 Dec 2009 16:17:58 -0000
@@ -9,17 +9,15 @@
+ * - $first_new: Indicates whether this is the first topic with
+ *   new posts.

Wraps too early.

+++ modules/forum/forum.module 4 Dec 2009 16:17:58 -0000
@@ -855,6 +856,13 @@ function forum_get_topics($tid, $sortby,
+   

Trailing white-space here.

+++ modules/forum/forum.module 4 Dec 2009 16:17:58 -0000
@@ -855,6 +856,13 @@ function forum_get_topics($tid, $sortby,
+    if (($topic->new != 0) && (!$first_new_found)) {

Plenty of unnecessary parenthesis.

+++ modules/forum/forum.module 4 Dec 2009 16:17:58 -0000
@@ -1017,7 +1025,7 @@ function template_preprocess_forum_topic
-      $variables['topics'][$id]->icon = theme('forum_icon', array('new_posts' => $topic->new, 'num_posts' => $topic->comment_count, 'comment_mode' => $topic->comment_mode, 'sticky' => $topic->sticky));
+      $variables['topics'][$id]->icon = theme('forum_icon', array('new_posts' => $topic->new, 'num_posts' => $topic->comment_count, 'comment_mode' => $topic->comment_mode, 'sticky' => $topic->sticky, $topic->first_new));

This is either not required or it is missing an array key.

I'm on crack. Are you, too?

#50

brianV - December 8, 2009 - 06:34
Status:needs work» needs review

@sun

Turns out I rerolled that badly. Re-rolled with your suggestions changed, the theme() call fixed, and tested thoroughly this time.

@Dries

As requested, I have also attached a screenshot which illustrates the change. Basically, there is no graphical change. The only change is that the first new icon (green) gets the <a id="new" /> (green codeblock) while the remaining icons (red) don't get it. (red codeblock).

This is, of course, used in links to the first new topic in the forum (eg., http://example.com/forum/1#new).

Previous behaviour was that each new forum icon would receive the <a id="new" />. This breaks XHTML validation, as each id element is required to have a unique name.

AttachmentSizeStatusTest resultOperations
405238-forum_duplicate_id-rev15.patch3.41 KBIdlePassed on all environments.View details | Re-test
Screenshot-1.png50.55 KBIgnoredNoneNone

#51

sun - December 8, 2009 - 06:56
Status:needs review» reviewed & tested by the community

Thank you, well done!

 
 

Drupal is a registered trademark of Dries Buytaert.