r48249 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r48248‎ | r48249 | r48250 >
Date:01:07, 10 March 2009
Author:werdna
Status:resolved (Comments)
Tags:
Comment:
* (bug 4582) Provide preference-based autoformatting of unlinked dates with the dateformat
parser function.
Modified paths:
  • /trunk/phase3/includes/parser/CoreParserFunctions.php (modified) (history)
  • /trunk/phase3/includes/parser/DateFormatter.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/parser/CoreParserFunctions.php
@@ -67,6 +67,7 @@
6868 $parser->setFunctionHook( 'subjectpagename', array( __CLASS__, 'subjectpagename' ), SFH_NO_HASH );
6969 $parser->setFunctionHook( 'subjectpagenamee', array( __CLASS__, 'subjectpagenamee' ), SFH_NO_HASH );
7070 $parser->setFunctionHook( 'tag', array( __CLASS__, 'tagObj' ), SFH_OBJECT_ARGS );
 71+ $parser->setFunctionHook( 'formatdate', array( __CLASS__, 'formatDate' ), SFH_NO_HASH );
7172
7273 if ( $wgAllowDisplayTitle ) {
7374 $parser->setFunctionHook( 'displaytitle', array( __CLASS__, 'displaytitle' ), SFH_NO_HASH );
@@ -87,6 +88,14 @@
8889 return array( 'found' => false );
8990 }
9091 }
 92+
 93+ static function formatDate( $parser, $date ) {
 94+ $df = DateFormatter::getInstance();
 95+
 96+ $pref = $parser->mOptions->getDateFormat();
 97+ $date = $df->reformat( $pref, $date, false );
 98+ return $date;
 99+ }
91100
92101 static function ns( $parser, $part1 = '' ) {
93102 global $wgContLang;
Index: trunk/phase3/includes/parser/DateFormatter.php
@@ -41,11 +41,11 @@
4242 $this->regexTrail = '(?![a-z])/iu';
4343
4444 # Partial regular expressions
45 - $this->prxDM = '\[\[(\d{1,2})[ _](' . $this->monthNames . ')]]';
46 - $this->prxMD = '\[\[(' . $this->monthNames . ')[ _](\d{1,2})]]';
47 - $this->prxY = '\[\[(\d{1,4}([ _]BC|))]]';
48 - $this->prxISO1 = '\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})]]';
49 - $this->prxISO2 = '\[\[(-?\d{4})-(\d{2})-(\d{2})]]';
 45+ $this->prxDM = '\[\[(\d{1,2})[ _](' . $this->monthNames . ')\]\]';
 46+ $this->prxMD = '\[\[(' . $this->monthNames . ')[ _](\d{1,2})\]\]';
 47+ $this->prxY = '\[\[(\d{1,4}([ _]BC|))\]\]';
 48+ $this->prxISO1 = '\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})\]\]';
 49+ $this->prxISO2 = '\[\[(-?\d{4})-(\d{2})-(\d{2})\]\]';
5050
5151 # Real regular expressions
5252 $this->regexes[self::DMY] = "/{$this->prxDM} *,? *{$this->prxY}{$this->regexTrail}";
@@ -117,7 +117,7 @@
118118 * @param $preference String: User preference
119119 * @param $text String: Text to reformat
120120 */
121 - function reformat( $preference, $text ) {
 121+ function reformat( $preference, $text, $linked = true ) {
122122 if ( isset( $this->preferences[$preference] ) ) {
123123 $preference = $this->preferences[$preference];
124124 } else {
@@ -138,7 +138,17 @@
139139 # Default
140140 $this->mTarget = $i;
141141 }
142 - $text = preg_replace_callback( $this->regexes[$i], array( &$this, 'replace' ), $text );
 142+ $regex = $this->regexes[$i];
 143+
 144+ // Horrible hack
 145+ if (!$linked) {
 146+ $regex = str_replace( array( '\[\[', '\]\]' ), '', $regex );
 147+ }
 148+
 149+ // Another horrible hack
 150+ $this->mLinked = $linked;
 151+ $text = preg_replace_callback( $regex, array( &$this, 'replace' ), $text );
 152+ unset($this->mLinked);
143153 }
144154 return $text;
145155 }
@@ -148,6 +158,10 @@
149159 */
150160 function replace( $matches ) {
151161 # Extract information from $matches
 162+ $linked = true;
 163+ if ( isset( $this->mLinked ) )
 164+ $linked = $this->mLinked;
 165+
152166 $bits = array();
153167 $key = $this->keys[$this->mSource];
154168 for ( $p=0; $p < strlen($key); $p++ ) {
@@ -156,43 +170,50 @@
157171 }
158172 }
159173
160 - return $this->formatDate( $bits );
 174+ return $this->formatDate( $bits, $linked );
161175 }
162176
163 - function formatDate( $bits ) {
 177+ function formatDate( $bits, $link = true ) {
164178 $format = $this->targets[$this->mTarget];
 179+
 180+ if (!$link) {
 181+ // strip piped links
 182+ $format = preg_replace( '/\[\[[^|]+\|([^\]]+)\]\]/', '$1', $format );
 183+ // strip remaining links
 184+ $format = str_replace( array( '[[', ']]' ), '', $format );
 185+ }
165186
166187 # Construct new date
167188 $text = '';
168189 $fail = false;
169190
170191 // Pre-generate y/Y stuff because we need the year for the <span> title.
171 - if ( !isset( $bits['y'] ) )
 192+ if ( !isset( $bits['y'] ) && isset( $bits['Y'] ) )
172193 $bits['y'] = $this->makeIsoYear( $bits['Y'] );
173 - if ( !isset( $bits['Y'] ) )
 194+ if ( !isset( $bits['Y'] ) && isset( $bits['y'] ) )
174195 $bits['Y'] = $this->makeNormalYear( $bits['y'] );
 196+
 197+ if ( !isset( $bits['m'] ) ) {
 198+ $m = $this->makeIsoMonth( $bits['F'] );
 199+ if ( !$m || $m == '00' ) {
 200+ $fail = true;
 201+ } else {
 202+ $bits['m'] = $m;
 203+ }
 204+ }
 205+
 206+ if ( !isset($bits['d']) ) {
 207+ $bits['d'] = sprintf( '%02d', $bits['j'] );
 208+ }
175209
176210 for ( $p=0; $p < strlen( $format ); $p++ ) {
177211 $char = $format{$p};
178212 switch ( $char ) {
179213 case 'd': # ISO day of month
180 - if ( !isset($bits['d']) ) {
181 - $text .= sprintf( '%02d', $bits['j'] );
182 - } else {
183 - $text .= $bits['d'];
184 - }
 214+ $text .= $bits['d'];
185215 break;
186216 case 'm': # ISO month
187 - if ( !isset($bits['m']) ) {
188 - $m = $this->makeIsoMonth( $bits['F'] );
189 - if ( !$m || $m == '00' ) {
190 - $fail = true;
191 - } else {
192 - $text .= $m;
193 - }
194 - } else {
195 - $text .= $bits['m'];
196 - }
 217+ $text .= $bits['m'];
197218 break;
198219 case 'y': # ISO year
199220 $text .= $bits['y'];
@@ -228,7 +249,12 @@
229250 $text = $matches[0];
230251 }
231252
232 - $isoDate = $bits['y'].$bits['m'].$bits['d'];
 253+ $isoBits = array();
 254+ if ( isset($bits['y']) )
 255+ $isoBits[] = $bits['y'];
 256+ $isoBits[] = $bits['m'];
 257+ $isoBits[] = $bits['d'];
 258+ $isoDate = implode( '-', $isoBits );;
233259
234260 // Output is not strictly HTML (it's wikitext), but <span> is whitelisted.
235261 $text = Xml::tags( 'span',
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -338,6 +338,7 @@
339339 'numberingroup' => array( 1, 'NUMBERINGROUP', 'NUMINGROUP' ),
340340 'staticredirect' => array( 1, '__STATICREDIRECT__' ),
341341 'protectionlevel' => array( 1, 'PROTECTIONLEVEL' ),
 342+ 'formatdate' => array( 0, 'formatdate', 'dateformat' ),
342343 );
343344
344345 /**

Follow-up revisions

RevisionCommit summaryAuthorDate
r48254Tweak r48249 -- allow specification of the default format, and require the da...werdna05:19, 10 March 2009
r70651Revert r70533 and the piece of r70501 that it tried to fix. Note and open bug...platonides21:21, 7 August 2010

Comments

#Comment by Anomie (talk | contribs)   03:41, 10 March 2009

{{#formatdate:9 March 2009}} outputs the following:

9 <span class="mw-formatted-date" title="0009-03-20">March 20, 09</span>

Also, if you could throw in a magic word (like DEFAULTSORT does for category sort keys) to make #formatdate use a particular format for users with no preference, that would make it even more useful. Otherwise enwiki people will just complain "It's still no good because IP users will see mismatched dates".

#Comment by Werdna (talk | contribs)   05:19, 10 March 2009

Thanks for the feedback

Fixed in r48254.

#Comment by Tony1 (talk | contribs)   04:28, 10 March 2009

Is there a list of specs? Is there a demonstration? Has it been tested?

#Comment by Werdna (talk | contribs)   04:34, 10 March 2009

This is a very simple fix. Specs are "It applies the same magic applied to linked dates without linking them" (i.e. what I wrote in the commit message and release notes)

There was no need to set up a live demonstration, although you're welcome to do it yourself.

Like anything committed to subversion (we hope), it was tested before committing.

#Comment by Locke Cole (talk | contribs)   06:05, 10 March 2009

Would you like fries with that?

#Comment by UC Bill (talk | contribs)   15:16, 10 March 2009

First, a nitpick: Escaping closing braces is unnecessary unless you're within the context of an open brace, so your changes to the prx* lines don't actually do anything... however, if you just want to clean up the code to be easier to read, you should also change the prxISO1 (missed a set of closing braces there.)

More substantially, I'm not so sure about the changes you made to the case statements, getting rid of the checks on the "ISO" bits. Note that there's a transformation there from the 'j' or 'F' bits into their equivalent 'd' or 'm' form, which is no longer taking place in the changed version. I'll checkout a fresh copy of the code and try to come up with some test cases, but you might want to look into it as well.

Good work, by the way! I think this might make a template solution feasible, or at least be a step in that direction.


#Comment by UC Bill (talk | contribs)   15:20, 10 March 2009

Gah. I meant "brackets" not "braces" (gotta remember which are the square and which are the curly.. :)

#Comment by UC Bill (talk | contribs)   15:40, 10 March 2009

Ah, thanks Werdna for the explanation on enwiki. For the record, the 'j' and 'F' bits I was referring to are now taken care of before the case statements are even reached. I'll still checkout a fresh copy and run some test cases, if only to shut up the critics on enwiki who are complaining about the lack of transparency in the test/commit process. I expect the code will work fine, though.

#Comment by Brion VIBBER (talk | contribs)   23:03, 18 March 2009

This really needs parser test cases...

#Comment by Remember the dot (talk | contribs)   17:05, 20 March 2009

How would this function be used? Please give specific examples.

#Comment by Tony1 (talk | contribs)   14:54, 11 April 2009

Pity IP users and the vanishingly small proportion of registered users who choose a preference will see different displays: that is asking for trouble. Pity about the total failure to deal with all of the other major problems with the blue-wash autoformatting, like date ranges (getting the en dash, spaced or unspaced, right, and not requiring huge amounts of redundancy, such as "January 4 – January 6, 1980". And has it been tested, we all want to know.

#Comment by Werdna (talk | contribs)   15:18, 11 April 2009

With respect, what on Earth are you on about?

If there is a specific problem with this revision, please let me know and I'll endeavour to fix it. If you have a specific question, please ask it and I'll endeavour to answer it.

Random rants with no particular actionable statements will probably be ignored.

Status & tagging log