Extension talk:News

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
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'.

<?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; }	} }

?>

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)