Index: trunk/phase3/includes/CategoryPage.php |
— | — | @@ -372,62 +372,60 @@ |
373 | 373 | * Format a list of articles chunked by letter in a three-column |
374 | 374 | * list, ordered vertically. |
375 | 375 | * |
| 376 | + * TODO: Take the headers into account when creating columns, so they're |
| 377 | + * more visually equal. |
| 378 | + * |
| 379 | + * More distant TODO: Scrap this and use CSS columns, whenever IE finally |
| 380 | + * supports those. |
| 381 | + * |
376 | 382 | * @param $articles Array |
377 | 383 | * @param $articles_start_char Array |
378 | 384 | * @return String |
379 | 385 | * @private |
380 | 386 | */ |
381 | 387 | function columnList( $articles, $articles_start_char ) { |
382 | | - // divide list into three equal chunks |
383 | | - $chunk = (int) ( count( $articles ) / 3 ); |
384 | | - $remaining = count( $articles ) % 3; |
| 388 | + $columns = array_combine( $articles, $articles_start_char ); |
| 389 | + # Split into three columns |
| 390 | + $columns = array_chunk( $columns, ceil( count( $columns )/3 ), true /* preserve keys */ ); |
385 | 391 | |
386 | | - // get and display header |
387 | | - $r = '<table width="100%"><tr valign="top">'; |
| 392 | + $ret = '<table width="100%"><tr valign="top"><td>'; |
| 393 | + $prevchar = null; |
388 | 394 | |
389 | | - $prev_start_char = 'none'; |
| 395 | + foreach ( $columns as $column ) { |
| 396 | + $colContents = array(); |
390 | 397 | |
391 | | - // loop through the chunks |
392 | | - for( $startChunk = 0, $endChunk = $chunk, $chunkIndex = 0; |
393 | | - $chunkIndex < 3; |
394 | | - $chunkIndex++, $startChunk = $endChunk, $endChunk += $remaining == 0 ? $chunk : $chunk + 1 ) |
395 | | - { |
396 | | - $r .= "<td>\n"; |
397 | | - $atColumnTop = true; |
| 398 | + # Kind of like array_flip() here, but we keep duplicates in an |
| 399 | + # array instead of dropping them. |
| 400 | + foreach ( $column as $article => $char ) { |
| 401 | + if ( !isset( $colContents[$char] ) ) { |
| 402 | + $colContents[$char] = array(); |
| 403 | + } |
| 404 | + $colContents[$char][] = $article; |
| 405 | + } |
398 | 406 | |
399 | | - // output all articles in category |
400 | | - for ($index = $startChunk ; |
401 | | - $index < $endChunk && $index < count($articles); |
402 | | - $index++ ) |
403 | | - { |
404 | | - // check for change of starting letter or beginning of chunk |
405 | | - if ( ($index == $startChunk) || |
406 | | - ($articles_start_char[$index] != $articles_start_char[$index - 1]) ) |
407 | | - |
408 | | - { |
409 | | - if( $atColumnTop ) { |
410 | | - $atColumnTop = false; |
411 | | - } else { |
412 | | - $r .= "</ul>\n"; |
413 | | - } |
414 | | - $cont_msg = ""; |
415 | | - if ( $articles_start_char[$index] == $prev_start_char ) |
416 | | - $cont_msg = ' ' . wfMsgHtml( 'listingcontinuesabbrev' ); |
417 | | - $r .= "<h3>" . htmlspecialchars( $articles_start_char[$index] ) . "$cont_msg</h3>\n<ul>"; |
418 | | - $prev_start_char = $articles_start_char[$index]; |
| 407 | + $first = true; |
| 408 | + foreach ( $colContents as $char => $articles ) { |
| 409 | + $ret .= '<h3>' . htmlspecialchars( $char ); |
| 410 | + if ( $first && $char === $prevchar ) { |
| 411 | + # We're continuing a previous chunk at the top of a new |
| 412 | + # column, so add " cont." after the letter. |
| 413 | + $ret .= ' ' . wfMsgHtml( 'listingcontinuesabbrev' ); |
419 | 414 | } |
| 415 | + $ret .= "</h3>\n"; |
420 | 416 | |
421 | | - $r .= "<li>{$articles[$index]}</li>"; |
| 417 | + $ret .= '<ul><li>'; |
| 418 | + $ret .= implode( "</li>\n<li>", $articles ); |
| 419 | + $ret .= '</li></ul>'; |
| 420 | + |
| 421 | + $first = false; |
| 422 | + $prevchar = $char; |
422 | 423 | } |
423 | | - if( !$atColumnTop ) { |
424 | | - $r .= "</ul>\n"; |
425 | | - } |
426 | | - $r .= "</td>\n"; |
427 | 424 | |
428 | | - |
| 425 | + $ret .= "</td>\n<td>"; |
429 | 426 | } |
430 | | - $r .= '</tr></table>'; |
431 | | - return $r; |
| 427 | + |
| 428 | + $ret .= '</td></tr></table>'; |
| 429 | + return $ret; |
432 | 430 | } |
433 | 431 | |
434 | 432 | /** |