Added code to implement Dublin Core and Creative Commons RDF metadata.

If these features are turned on (with global flags), a metadata link tag is
provided to the appropriate action ('dublincore' or 'creativecommons'). When
the wiki script receives these actions, it creates RDF files on the fly.

Also includes two valuable general functions: one to show an HTTP error
(used when the flags are turned off), and one to do content negotiation
(used to determine the MIME type for RDF files).

A helper function is also added to page output to display metadata links.
This commit is contained in:
Evan Prodromou 2004-04-04 21:58:05 +00:00
parent f5add7034c
commit 22f8c4ce37
6 changed files with 158 additions and 3 deletions

View file

@ -292,5 +292,17 @@ if( !isset( $wgCommandLineMode ) ) {
}
# Show seconds in Recent Changes
$wgRCSeconds = false
$wgRCSeconds = false;
# RDF metadata toggles
$wgEnableDublinCoreRdf = false;
$wgEnableCreativeCommonsRdf = false;
# Override for copyright metadata.
$wgRightsPage = NULL;
$wgRightsUrl = NULL;
$wgRightsText = NULL;
?>

View file

@ -845,4 +845,101 @@ function wfVarDump( $var )
}
}
/* Provide a simple HTTP error. */
function wfHttpError($code, $label, $desc) {
global $wgOut;
$wgOut->disable();
header("HTTP/1.0 $code $label");
header("Status: $code $label");
$wgOut->sendCacheControl();
/* Don't send content if it's a HEAD request. */
if (strcmp($HTTP_SERVER_VARS['REQUEST_METHOD'],'HEAD') != 0) {
header("Content-type: text/plain");
print "$desc\n";
}
}
# Converts an Accept-* header into an array mapping string values to quality factors
function wfAcceptToPrefs($accept, $def = "*/*") {
# No arg means accept anything (per HTTP spec)
if (!$accept) {
return array($def => 1);
}
$prefs = array();
$parts = explode(",", $accept);
foreach ($parts as $part) {
#FIXME: doesn't deal with params like 'text/html; level=1'
list($value, $qpart) = explode(";", $part);
if (!isset($qpart)) {
$prefs[$value] = 1;
} else if (preg_match('/q\s*=\s*(\d*\.\d+)/', $qpart, $match)) {
$prefs[$value] = $match[1];
}
}
return $prefs;
}
/* private */ function mimeTypeMatch($type, $avail) {
if (array_key_exists($type, $avail)) {
return $type;
} else {
$parts = explode('/', $type);
if (array_key_exists($parts[0] . '/*', $avail)) {
return $parts[0] . '/*';
} else if (array_key_exists('*/*', $avail)) {
return '*/*';
} else {
return NULL;
}
}
}
#FIXME: doesn't handle params like 'text/plain; charset=UTF-8'
#XXX: generalize to negotiate other stuff
function wfNegotiateType($cprefs, $sprefs) {
$combine = array();
foreach (array_keys($sprefs) as $type) {
$parts = explode('/', $type);
if ($parts[1] != '*') {
$ckey = mimeTypeMatch($type, $cprefs);
if ($ckey) {
$combine[$type] = $sprefs[$type] * $cprefs[$ckey];
}
}
}
foreach (array_keys($cprefs) as $type) {
$parts = explode('/', $type);
if ($parts[1] != '*' && !array_key_exists($type, $sprefs)) {
$skey = mimeTypeMatch($type, $sprefs);
if ($skey) {
$combine[$type] = $sprefs[$skey] * $cprefs[$type];
}
}
}
$bestq = 0;
$besttype = NULL;
foreach (array_keys($combine) as $type) {
if ($combine[$type] > $bestq) {
$besttype = $type;
$bestq = $combine[$type];
}
}
return $besttype;
}
?>

View file

@ -46,6 +46,12 @@ class OutputPage {
function addKeyword( $text ) { array_push( $this->mKeywords, $text ); }
function addLink( $rel, $rev, $target, $type="", $media="" ) { array_push( $this->mLinktags, array( $rel, $rev, $target, $type, $media ) ); }
function addMetadataLink( $type, $target ) {
static $haveMeta = false;
$this->addLink(($haveMeta) ? "alternate meta" : "meta", "", $target, $type);
$haveMeta = true;
}
# checkLastModified tells the client to use the client-cached page if
# possible. If sucessful, the OutputPage is disabled so that
# any future call to OutputPage->output() have no effect. The method

View file

@ -95,15 +95,30 @@ class Skin {
function initPage( &$out )
{
global $wgStyleSheetPath;
$fname = "Skin::initPage";
wfProfileIn( $fname );
$out->addLink( "shortcut icon", "", "/favicon.ico" );
$this->addMetadataLinks($out);
wfProfileOut( $fname );
}
function addMetadataLinks( &$out ) {
global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
if ($action == 'view') {
# note: buggy CC software only reads first "meta" link
if ($wgEnableCreativeCommonsRdf) {
$out->addMetadataLink('application/rdf+xml', wfLocalUrl($wgTitle->getPrefixedURL(), "action=creativecommons"));
}
if ($wgEnableDublinCoreRdf) {
$out->addMetadataLink('application/rdf+xml', wfLocalUrl($wgTitle->getPrefixedURL(), "action=dublincore"));
}
}
}
function outputPage( &$out ) {
global $wgDebugComments;

View file

@ -108,6 +108,22 @@ if ( $search = $wgRequest->getText( 'search' ) ) {
case "print":
$wgArticle->view();
break;
case "dublincore":
if (!$wgEnableDublinCoreRdf) {
wfHttpError(403, "Forbidden", wfMsg("nodublincore"));
} else {
include_once("Metadata.php");
wfDublinCoreRdf($wgArticle);
}
break;
case "creativecommons":
if (!$wgEnableCreativeCommonsRdf) {
wfHttpError(403, "Forbidden", wfMsg("nocreativecommons"));
} else {
include_once("Metadata.php");
wfCreativeCommonsRdf($wgArticle);
}
break;
case "edit":
case "submit":
if( !$wgCommandLineMode && !$wgRequest->checkSessionCookie() ) {

View file

@ -1548,6 +1548,15 @@ amusement.",
'tooltip-specialpages' => 'List of all special pages',
'tooltip-upload' => 'Upload images or media files [alt-u]',
'tooltip-specialpage' => 'This is a special page, you can\'t edit the page itself.',
# Metadata
"nodublincore" => "Dublin Core RDF metadata disabled for this server.",
"nocreativecommons" => "Creative Commons RDF metadata disabled for this server.",
"notacceptable" => "The wiki server can't provide data in a format your client can read.",
# Attribution
"anonymous" => "Anonymous user(s) of $wgSitename"
);
#--------------------------------------------------------------------------