diff --git a/src/IDF/Template/Markdown.php b/src/IDF/Template/Markdown.php
index c058d63..82b12cd 100644
--- a/src/IDF/Template/Markdown.php
+++ b/src/IDF/Template/Markdown.php
@@ -55,8 +55,17 @@ class IDF_Template_Markdown extends Pluf_Template_Tag
$text = IDF_Template_safePregReplace('#\[\[([A-Za-z0-9\-]+)\]\]#im',
array($this, 'callbackWikiPageNoName'),
$text);
+
$filter = new IDF_Template_MarkdownPrefilter();
- echo $filter->go(Pluf_Text_MarkDown_parse($text));
+ $text = $filter->go(Pluf_Text_MarkDown_parse($text));
+
+ // Replace [[!ResourceName]] with corresponding HTML for the resource;
+ // we need to do that after the HTML filtering as we'd otherwise be unable to use
+ // certain HTML elements, such as iframes, that are used to display text content
+ // FIXME: no support for escaping yet in place
+ echo IDF_Template_safePregReplace('#\[\[!([A-Za-z0-9\-]+)(?:,\s*([^\]]+))?\]\]#im',
+ array($this, 'callbackWikiResource'),
+ $text);
}
function callbackWikiPageNoName($m)
@@ -80,6 +89,85 @@ class IDF_Template_Markdown extends Pluf_Template_Tag
return ''.$m[1].'';
}
+ function callbackWikiResource($m)
+ {
+ @list($match, $resourceName, $opts) = $m;
+
+ if (!$this->request->rights['hasWikiAccess']) {
+ return ''.$match.'';
+ }
+
+ $sql = new Pluf_SQL('project=%s AND title=%s',
+ array($this->project->id, $resourceName));
+ $resources = Pluf::factory('IDF_Wiki_Resource')->getList(array('filter'=>$sql->gen()));
+
+ if ($resources->count() == 0) {
+ if ($this->request->user->isAnonymous()) {
+ return ''.$match.'';
+ }
+
+ $url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::createResource',
+ array($this->project->shortname),
+ array('name' => $resourceName));
+ return ''.
+ ''.$match.'';
+ }
+
+ // by default, render the most recent revision
+ $resourceRevision = $resources[0]->get_current_revision();
+
+ list($urlConf, $urlMatches) = $this->request->view;
+
+ // if we currently look at an existing wiki page, look up its name and find the proper resource (if any)
+ if ($urlConf['model'] == 'IDF_Views_Wiki' && $urlConf['method'] == 'viewPage') {
+ $sql = new Pluf_SQL('project=%s AND title=%s',
+ array($this->project->id, $urlMatches[2]));
+ $pages = Pluf::factory('IDF_Wiki_Page')->getList(array('filter'=>$sql->gen()));
+ if ($pages->count() == 0) throw new Exception('page not found');
+ $pageRevision = $pages[0]->get_current_revision();
+
+ // if we look at an old version of the page, figure out the resource version back then
+ if (isset($this->request->GET['rev']) and preg_match('/^[0-9]+$/', $this->request->GET['rev'])) {
+ $pageRevision = Pluf_Shortcuts_GetObjectOr404('IDF_Wiki_PageRevision',
+ $this->request->GET['rev']);
+ if ($pageRevision->wikipage != $pages[0]->id) {
+ return ''.$match.'';
+ }
+ }
+
+ $sql = new Pluf_SQL('wikiresource=%s AND idf_wiki_pagerevision_id=%s',
+ array($resources[0]->id, $pageRevision->id));
+ $resourceRevision = Pluf::factory('IDF_Wiki_ResourceRevision')->getOne(
+ array('filter' => $sql->gen(), 'view' => 'join_pagerevision'));
+
+ }
+
+ $validOpts = array(
+ 'align' => '/^(left|right|center)$/',
+ 'width' => '/^\d+(%|px|em)?$/',
+ 'height' => '/^\d+(%|px|em)?$/',
+ 'preview' => '/^yes|no$/',
+ 'title' => '/.+/',
+ );
+
+ $parsedOpts = array();
+ // FIXME: no support for escaping yet in place
+ $opts = preg_split('/\s*,\s*/', $opts, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ((array)@$opts as $opt)
+ {
+ list($key, $value) = preg_split('/\s*=\s*/', $opt, 2);
+ if (!array_key_exists($key, $validOpts)) {
+ continue;
+ }
+ if (!preg_match($validOpts[$key], $value)) {
+ continue;
+ }
+ $parsedOpts[$key] = $value;
+ }
+
+ return $resourceRevision->render($parsedOpts);
+ }
+
function callbackEmbeddedDoc($m)
{
$scm = IDF_Scm::get($this->request->project);
diff --git a/src/IDF/Wiki/PageRevision.php b/src/IDF/Wiki/PageRevision.php
index 295bbd0..2b4c848 100644
--- a/src/IDF/Wiki/PageRevision.php
+++ b/src/IDF/Wiki/PageRevision.php
@@ -99,6 +99,14 @@ class IDF_Wiki_PageRevision extends Pluf_Model
'type' => 'normal',
),
);
+ $table = $this->_con->pfx.'idf_wiki_pagerevision_idf_wiki_resourcerevision_assoc';
+ $this->_a['views'] = array(
+ 'join_pagerevision' =>
+ array(
+ 'join' => 'LEFT JOIN '.$table
+ .' ON idf_wiki_pagerevision_id=id',
+ ),
+ );
}
function changedRevision()
diff --git a/src/IDF/Wiki/ResourceRevision.php b/src/IDF/Wiki/ResourceRevision.php
index 4a0a3b7..13a8642 100644
--- a/src/IDF/Wiki/ResourceRevision.php
+++ b/src/IDF/Wiki/ResourceRevision.php
@@ -101,6 +101,14 @@ class IDF_Wiki_ResourceRevision extends Pluf_Model
'verbose' => __('creation date'),
),
);
+ $table = $this->_con->pfx.'idf_wiki_pagerevision_idf_wiki_resourcerevision_assoc';
+ $this->_a['views'] = array(
+ 'join_pagerevision' =>
+ array(
+ 'join' => 'LEFT JOIN '.$table
+ .' ON idf_wiki_resourcerevision_id=id',
+ ),
+ );
}
function __toString()
@@ -165,11 +173,22 @@ class IDF_Wiki_ResourceRevision extends Pluf_Model
$this->get_wikiresource()->id, $this->id, $this->fileext);
}
- function getFileURL()
+ function getViewURL()
{
+ $prj = $this->get_wikiresource()->get_project();
+ $resource = $this->get_wikiresource();
+ return Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::viewResource',
+ array($prj->shortname, $resource->title),
+ array('rev' => $this->id));
+ }
+
+ function getRawURL($attachment = false)
+ {
+ $query = $attachment ? array('attachment' => 1) : array();
$prj = $this->get_wikiresource()->get_project();
return Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::rawResource',
- array($prj->shortname, $this->id));
+ array($prj->shortname, $this->id),
+ $query);
}
/**
@@ -195,20 +214,78 @@ class IDF_Wiki_ResourceRevision extends Pluf_Model
}
/**
- * Renders the resource
+ * Renders the resource with the given view options, including a link to the resource' detail page
*/
- function render()
+ function render($opts = array())
{
- $url = $this->getFileURL();
+ // give some reasonable defaults
+ $opts = array_merge(array(
+ 'align' => 'left',
+ 'width' => '',
+ 'height' => '',
+ 'preview' => 'yes', // if possible
+ 'title' => '',
+ ), $opts);
+
+ $attrs = array('class="resource-container"');
+ $styles = array();
+ if (!empty($opts['align'])) {
+ switch ($opts['align']) {
+ case 'left':
+ $styles[] = 'float: left';
+ $styles[] = 'margin-right: 10px';
+ break;
+ case 'center':
+ $styles[] = 'margin: 0 auto 0 auto';
+ break;
+ case 'right':
+ $styles[] = 'float: right';
+ $styles[] = 'margin-left: 10px';
+ break;
+ }
+ }
+ if (!empty($opts['width'])) {
+ $styles[] = 'width:'.$opts['width'];
+ }
+ if (!empty($opts['height'])) {
+ $styles[] = 'height:'.$opts['height'];
+ }
+
+ $raw = $this->renderRaw();
+ $viewUrl = $this->getViewURL();
+ $download = '';
+ $html = '
{$resource.summary}
-{$rev.render()|unsafe}
+{assign $preview = $rev.renderRaw()} +{if $preview == ''} + {assign $preview = __('Unable to render preview for this MIME type.')} +{/if} +{$preview|unsafe}
-{aurl 'url', 'IDF_Views_Wiki::rawResource', array($project.shortname, $rev.id), array('attachment' => 1)}