Extension talk:News

Error
My wiki is 1.8.2, and i get this error: Fatal error: Call to undefined method DatabaseMysql::tableNamesN in /home/mazeikiu/domains/ mazeikiai.projektas.in/public_html/w/extensions/News/NewsRenderer.php on line 157

Any can help me? Thanks --88.222.212.231 12:24, 16 February 2007 (UTC)


 * Sure, upgrade to 1.9 -- Duesentrieb 14:17, 16 February 2007 (UTC)

Hm, are I can fix it for 1.8.2? :/

Just copy the function "tableNamesN" from the file in SVN "includes/Database.php" and copy to your installation. Works for me (Mediawiki v1.8.2) Jean-Lou Dupont 19:31, 20 February 2007 (UTC)

Can't install correctly
I tried to add the following line at the end (and anywhere else for that matter) in the LocalSettings.php file: require_once( "$IP/extensions/News/News.php" );

But it doesn't work. It only ends up writing the line at the start of the webpage. Any idea what I'm doing wrong? -- Kirjapan 22:34, 21 February 2007 (UTC)


 * add the line before the closing ?>-tag so it should look like this:

this might and actually should help.

Inserting in a Template
I ran into a problem whilst using the extension through a template (MW v1.8.2); "UNIQ" tags were appearing on the page. How do I get around this problem? Jean-Lou Dupont 17:57, 28 February 2007 (UTC)


 * Works fine for me on 1.10. But the parser is a strange beast, there probably have been some duptle changes in its working since 1.8. But then, I never said it would work with 1.8 :o)
 * So, sorry, no: I don't know how to get around this. And i don't have a 1.8 around to reproduce it. If you come up with a solution, please post it here. -- Duesentrieb ⇌ 22:57, 28 February 2007 (UTC)

inserting tables
It seems that tables (or rather, table rows) inside the NEWS section are not supported - neither with wiki markup (including the "!" template workaround), nor with raw HTML. Can you confirm (or even fix) that? Also, since this extension uses iterations anyway, would it be possible to define alternating styles (e.g to highlight odd rows)? -- FND 09:12, 27 March 2007 (UTC)


 * According to Duesentrieb, this extension uses template syntax, so table rows should be possible. However, each row is parsed individually, and it will not recognize table-row markup, without knowing that there is a table around it - and it can't really know that.

Fix for MW < 1.10
(code below) Voila, the extension now works for MW < 1.10 (at least 1.8.2 and 1.9.3)
 * Basically, you don't need to grab (or clone) the parser object. Just keep using the parser object you acquired when the class was created.
 * The next trick is to use the nifty function 'recursiveTagParse'.

-- Jean-Lou Dupont 19:07, 29 March 2007 (UTC)


 * Huh - am I missing anything? I've been using this extension with MW v1.9.2 for a few days now, and it seems to work just fine!?
 * Have you tried putting two or more of those tags on 1 page? or using it through a template call? or using the template defined format? That would be where one starts to have problems with the original version. Jean-Lou Dupont 11:04, 1 April 2007 (UTC)

Interresting... can you please provide a diff/patch of your changes, so i can check them against the original more easily? -- Duesentrieb ⇌ 19:05, 1 April 2007 (UTC)

Code: <?php /** * News renderer for News extension. * * @package MediaWiki * @subpackage Extensions * @author Daniel Kinzler, brightbyte.de * @copyright Â© 2007 Daniel Kinzler * @licence GNU General Public Licence 2.0 or later */

if( !defined( 'MEDIAWIKI' ) ) { echo( "Not a valid entry point.\n" ); die( 1 ); }


 * 1) no need to include, rely on autoloader
 * 2) global $IP;
 * 3) require_once( "$IP/includes/RecentChange.php" );
 * 4) require_once( "$IP/includes/ChangeList.php" );

class NewsRenderer { var $parser; var $skin;

var $usetemplate; var $templatetext; var $templateparser; var $templateoptions;

var $changelist;

var $namespaces; var $categories; var $types;

var $nominor; var $noanon; var $nobot; var $notalk;

var $onlynew; var $onlypatrolled;

function __construct( $templatetext, $argv, &$parser ) { global $wgContLang, $wgUser;

$this->skin = $wgUser->getSkin; $this->parser = $parser; $this->templatetext = $templatetext;

if ( !is_null( $this->templatetext ) ) { $this->templatetext = trim( $this->templatetext ); if ( $this->templatetext == '' ) $this->templatetext = NULL; }

$this->usetemplate = !is_null( $this->templatetext ); $this->templateparser = NULL; $this->templateoptions = NULL; #$template = @$argv['template']; if ( $this->usetemplate ) {

/* JLD:changes here $this->templateparser = clone $parser; $this->templateparser->setOutputType( OT_HTML ); #$this->templatetitle = Title::newFromText( $template, NS_TEMPLATE ); #$templatetext = $templateparser->fetchTemplate( $templatetitle ); $this->templateoptions = new ParserOptions; #$templateoptions->setRemoveComments( true ); #$templateoptions->setMaxIncludeSize( self::MAX_INCLUDE_SIZE ); }		else { $this->changelist = new OldChangesList( $this->skin ); }		$this->limit = @$argv['limit']; if ( !$this->limit ) $this->limit = 10; else if ( $this->limit > 100 ) $this->limit = 100; $this->unique = @$argv['unique']; if ( $this->unique === 'false' || $this->unique === 'no' || $this->unique === '0' ) $this->unique = false;

$this->namespaces = @$argv['namespaces']; if ( !is_null( $this->namespaces ) ) { $this->namespaces = preg_split('!\s*(\|\s*)+!', trim( $this->namespaces ) ); foreach ($this->namespaces as $i => $ns) { $ns = $wgContLang->lc($ns); if ( $ns === '-' || $ns === '0' || $ns === 'main' || $ns === 'article' ) { $this->namespaces[$i] = 0; } else { $this->namespaces[$i] = Namespace::getCanonicalIndex( $ns ); if ( $this->namespaces[$i] === false || $this->namespaces[$i] === NULL ) $this->namespaces[$i] = $wgContLang->getNsIndex( $ns ); }				if ( $this->namespaces[$i] === false || $this->namespaces[$i] === NULL ) unset( $this->namespaces[$i] ); }		}		$this->categories = @$argv['categories']; if ( !is_null( $this->categories ) ) { $this->categories = preg_split('!\s*(\|\s*)+!', trim( $this->categories ) ); foreach ($this->categories as $i => $n) { $t = Title::makeTitleSafe(NS_CATEGORY, $n); $n = $t->getDBkey; $this->categories[$i] = $n; }		}		$this->nominor = @$argv['nominor']; if ( $this->nominor === 'false' || $this->nominor === 'no' || $this->nominor === '0' ) $this->nominor = false; $this->nobot = @$argv['nobot']; if ( $this->nobot === 'false' || $this->nobot === 'no' || $this->nobot === '0' ) $this->nobot = false; $this->noanon = @$argv['noanon']; if ( $this->noanon === 'false' || $this->noanon === 'no' || $this->noanon === '0' ) $this->noanon = false; $this->notalk = @$argv['notalk']; if ( $this->notalk === 'false' || $this->notalk === 'no' || $this->notalk === '0' ) $this->notalk = false; $this->onlypatrolled = @$argv['onlypatrolled']; if ( $this->onlypatrolled === 'false' || $this->onlypatrolled === 'no' || $this->onlypatrolled === '0' ) $this->onlypatrolled = false; $this->onlynew = @$argv['onlynew']; if ( $this->onlynew === 'false' || $this->onlynew === 'no' || $this->onlynew === '0' ) $this->onlynew = false; $this->types = array( RC_EDIT, RC_NEW ); /* this doesn't work right if ( $unique ) { $group[] = 'rc_namespace AND rc_title'; }		*/	}

function query( $dbr, $limit, $offset = 0 ) { list( $trecentchanges, $tpage, $tcategorylinks ) = $dbr->tableNamesN( 'recentchanges', 'page', 'categorylinks' ); $where = array; $group = array; $select = "$trecentchanges.*"; $sql = "SELECT $select FROM $trecentchanges "; if ( $this->categories ) { $sql .= " JOIN $tpage ON page_namespace = rc_namespace AND page_title = rc_title "; $sql .= " JOIN $tcategorylinks ON cl_from = page_id ";

$where[] = 'cl_to IN ( ' . $dbr->makeList( $this->categories ) . ' )'; $group[] = 'rc_id'; }		if ( $this->nominor ) $where[] = 'rc_minor = 0'; if ( $this->nobot ) $where[] = 'rc_bot = 0'; if ( $this->noanon ) $where[] = 'rc_user > 0'; if ( $this->onlypatrolled ) $where[] = 'rc_patrolled = 1'; if ( $this->onlynew ) $where[] = 'rc_new = 1'; if ( $this->namespaces ) $where[] = 'rc_namespace IN ( ' . $dbr->makeList( $this->namespaces ) . ' )'; else { if ( $this->notalk ) $where[] = 'MOD(rc_namespace, 2) = 0'; $where[] = 'rc_namespace >= 0'; #ignore virtual namespaces (logs, mostly) }		$where[] = 'rc_type IN ( ' . $dbr->makeList( $this->types ) . ' )'; if ( $where ) $sql .= ' WHERE ( ' . implode( ' ) AND ( ', $where ) . ' )'; if ( $group ) $sql .= ' GROUP BY '. implode( ' AND ', $group ); $sql .= ' ORDER BY rc_timestamp DESC '; $sql = $dbr->limitResult( $sql, $limit, $offset ); $res = $dbr->query( $sql, 'newsxFetchRows' ); return $res; }	# The callback function for converting the input text to HTML output function renderNews { global $wgTitle;

$this->parser->disableCache; $dbr = wfGetDB( DB_SLAVE ); $text = ''; if ( !$this->usetemplate ) $text .= $this->changelist->beginRecentChangesList;

$remaining = $this->limit; $offset = 0; $ignore = array; #collect stuff we already have, when in unique mode while ( $remaining > 0 ) { #chunk loop for programmatic filter $chunk = $this->unique ? $remaining * 2 : $remaining; $res = $this->query( $dbr, $chunk, $offset ); $offset += $chunk; $has = false; while ( ( $remaining > 0 ) && ( $row = $dbr->fetchObject($res) ) ) { $has = true; if ( $this->unique && $row->rc_namespace >= 0 ) { $k = $row->rc_namespace. ':' . $row->rc_title; if ( isset( $ignore[$k] ) ) continue; $ignore[$k] = true; }				$t = $this->renderRow( $row ); $text .= trim($t). "\n"; #FIXME: handle blank lines at the end sanely. Paragraphs may be desired, but not when using lists. $remaining -= 1; }			$dbr->freeResult( $res ); if ( !$has ) break; #empty result set, stop trying }		if ( $this->usetemplate ) { #it's wikitext, parse // JLD:changes here $html = $this->parser->recursiveTagParse( $text ); }		else { #it's already html $text .= $this->changelist->endRecentChangesList; $html = $text; }		return $html; }	function renderRow( $row ) { global $wgUser, $wgLang; $change = RecentChange::newFromRow( $row ); $change->counter = 0; //hack if ( !$this->usetemplate ) { #$pagelink = $this->skin->makeKnownLinkObj( $title ); $this->changelist->insertDateHeader($dummy, $row->rc_timestamp); #dummy call to suppress date headers $html = $this->changelist->recentChangesLine( $change );

return $html; }		else { $params = array;

$params['namespace'] = $row->rc_namespace; $params['title'] = $row->rc_title;

$title = $change->getTitle; $params['pagename'] = $title->getPrefixedText;

$params['minor'] = $row->rc_minor ? 'true' : ''; $params['bot'] = $row->rc_bot ? 'true' : ''; $params['patrolled'] = $row->rc_patrolled ? 'true' : ''; $params['anon'] = ( $row->rc_user <= 0 ) ? 'true' : ''; #TODO: perhaps use (rc_user == rc_ip) instead? That would take care of entries from importing. $params['new'] = ( $row->rc_type == RC_NEW ) ? 'true' : '';

$params['type'] = $row->rc_type; $params['user'] = $row->rc_user_text; $params['rawtime'] = $row->rc_timestamp; $params['time'] = $wgLang->time( $row->rc_timestamp, true, true ); $params['date'] = $wgLang->date( $row->rc_timestamp, true, true ); $params['timeanddate'] = $wgLang->timeanddate( $row->rc_timestamp, true, true );

$params['old_len'] = $row->rc_old_len; $params['new_len'] = $row->rc_new_len;

$params['old_rev'] = $row->rc_last_oldid; $params['new_rev'] = $row->rc_this_oldid;

$diffq = $change->diffLinkTrail( false ); $params['diff'] = $diffq ? $title->getFullURL( $diffq ) : '';

$permaq = "oldid=". $row->rc_this_oldid; $params['permalink'] = $permaq ? $title->getFullURL( $permaq ) : '';

$params['comment'] = str_replace( array( , '|', '\ ), array( '&#123;&#123;', '&#125;&#125;', '&#124;', '$#39;' ), wfEscapeWikiText( $row->rc_comment ) ); // JLD:changes here $text = $this->parser->replaceVariables( $this->templatetext, $params ); return $text; }	} }

?>

Images shown rather than linked
If an image makes it to the list then it will be displayed, rather than linked to. Is there a workaround?


 * by (User: at )

Also, how does one get tables to work for this? I tried something like this, but it didn't work. This is using mw 1.10.0


 * To take away the "magic" from links to images and categories, use a leading ":", i.e.  :  instead of  
 * To make a table, use something like this:

 |--   |    |(User:    |)
 * HTH -- Duesentrieb ⇌ 00:10, 25 May 2007 (UTC)

insert News From a RSS feed
Hi, i prove to insert Links from a rss feed, but it dosent work..

What must i do?

real easy fix for 1.11
MW 1.11 requires hooks to return values. wfNewsSkinTemplateOutputPageBeforeExec almost works; all you gotta do is pop a "return" into it. News.php line 113:
 * true;

to
 * return true;</tt>

--Alxndr 13:07, 11 September 2007 (UTC)

show categories
Got title, user etc. - how do I post categories as well?

Old argument format?
Hi,

I'm an error saying:

Parser::replaceVariables called using the old argument format

When using the following code: * (User:, )

I have version 1.9.


 * Are you sure? Because that error is triggered by the new preprocessor code in 1.12 - and there's no resolution yet, see blow. -- Duesentrieb ⇌ 09:03, 31 March 2008 (UTC)

1.12.0 patch
I was trying to make a quick&dirty patch for this extension to work in MediaWiki 1.12.0. But I didn't find any sample code using the new-style parser-function replaceVariables. Is there any example available or is the issue with 1.12.0 quite more complex than this?

Thx --Matsch 21:15, 30 March 2008 (UTC)


 * After a quick chat with Tim Starling, who wrote the new Preprocessor code, it seems that a simple "replace variables" function does no longer exist. It would require an extra "dummy" implementation of PPFrame and PPNode, as far as I understand. I will not have time to look into it until May though. -- Duesentrieb ⇌ 09:02, 31 March 2008 (UTC)


 * Thanks for the info! Unfortunately, I believe I do not have the necessary experience with and understanding of MediaWiki, but I might have a look into it when I have some time. This News extension was one of the reasons for upgrading our old MediaWiki 1.6.something. Guess I'll have to wait. Thanks for your efforts though! -- Matsch 20:05, 2 April 2008 (UTC)


 * Find a quick&dirty patch for NewsRenderer.php on my page http://crazylinux.de/MediaWiki#Last_Updates_.28News.29. It will use the old Parser -- Jonathan 23:05, 14 April 2008 (UTC)
 * duh! thanks :) -- Duesentrieb ⇌ 08:43, 15 April 2008 (UTC)


 * Thx! Seems to work great so far (although I had problems applying your patch, cuz your diff is actually in the wrong direction. I never used patch before, though). -- Matsch 19:49, 15 April 2008 (UTC)


 * Thanks for your feedback. I optimized the patch and wrote some more documentation. Hope it's more clearer now :-) -- Jonathan 23:42, 15 April 2008 (UTC)
 * Could not get the patch to work. when patching i still get the message, that only 4of5 patches went through and even when i manuly apply the stuff taht ends up in the rejection file i get "Fatal error: Using $this when not in object context in /var/www/mediawiki/includes/Parser.php on line 563" when I add a newsfeed tag. any suggestions? --Jansch 13:14, 16 April 2008 (UTC)

A patch that makes it work with the new parser too is available at User:Duesentrieb/PPCustomFrame. This patch was created against 1.13alpha, but since the PP stuff didn't change much, I hape it applies to 1.12 cleanly too. PLease give feedback if it works fo you. -- Duesentrieb ⇌ 14:51, 26 June 2008 (UTC)

Problems with MW 1.13.0
If I add news tag I get empty page when adding news tag. In web servers error log there are PHP Fatal error: Call to protected method ChangesList::insertDateHeader from context 'NewsRenderer' in /News/NewsRenderer.php on line 494, referer: <url_begin>&action=edit. Do you know if this can be avoided somehow? Does this work better with MW 1.13.1 (is released after I upgraded to 1.13.0)?
 * I have heard about this one before, I'll look into it soon. I'm a bit surprised it didn't come up before, since I did test with 1.13 when it came out. Oh, well. Will poke at it next week. -- Duesentrieb ⇌ 10:38, 17 September 2008 (UTC)