Custom forge page rendering with project listing, home link,

improved contextual help.
This commit is contained in:
Thomas Keller 2011-12-27 03:16:09 +01:00
parent 6a3f1aed99
commit 5c04c87ff6
5 changed files with 144 additions and 42 deletions

View File

@ -25,10 +25,97 @@ Pluf::loadFunction('Pluf_Text_MarkDown_parse');
class IDF_Template_MarkdownForge extends Pluf_Template_Tag class IDF_Template_MarkdownForge extends Pluf_Template_Tag
{ {
function start($text) private $request;
public function start($text, $request)
{ {
$this->request = $request;
$filter = new IDF_Template_MarkdownPrefilter(); $filter = new IDF_Template_MarkdownPrefilter();
echo $filter->go(Pluf_Text_MarkDown_parse($text)); $text = $filter->go(Pluf_Text_MarkDown_parse($text));
// replace {}-macros with the corresponding template rendering
echo IDF_Template_safePregReplace('#\{(\w+)(?:,\s*([^\}]+))?\}#im',
array($this, 'callbackMacros'),
$text);
}
public function callbackMacros($matches)
{
@list(, $macro, $opts) = $matches;
$known_macros = array('projectlist');
if (!in_array($macro, $known_macros)) {
return $matches[0];
}
if (empty($opts)) {
$opts = array();
}
$callbackName = 'callback'.ucfirst(strtolower($macro)).'Macro';
return $this->callbackProjectlistMacro($opts);
}
public function callbackProjectlistMacro($opts)
{
$validOpts = array(
'label' => '/^\d+|(\w+:)?\w+$/',
'order' => '/^name|activity$/',
'limit' => '/^\d+$/',
);
$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;
}
$tag = false;
if (!empty($parsedOpts['label'])) {
if (is_numeric($parsedOpts['label'])) {
$tag = Pluf::factory('IDF_Tag')->get($parsedOpts['label']);
} else {
@list($class, $name) = preg_split('/:/', $parsedOpts['label'], 2);
if (empty($name)) {
$name = $class;
$class = IDF_TAG_DEFAULT_CLASS;
}
$sql = new Pluf_SQL('class=%s AND lcname=%s AND project=0',
array(strtolower($class), mb_strtolower($name)));
$tag = Pluf::factory('IDF_Tag')->getOne(array('filter' => $sql->gen()));
}
// ignore non-global tags
if ($tag !== false && $tag->project > 0) {
$tag = false;
}
}
$order = 'name';
if (!empty($parsedOpts['order'])) {
$order = $parsedOpts['order'];
}
$projects = IDF_Views::getProjects($this->request->user, $tag, $order);
if (!empty($parsedOpts['limit']) && $parsedOpts['limit'] < count($projects)) {
// there is no array_slice on ArrayObject, do'h!
$projectsCopy = array();
for ($i=0; $i<$parsedOpts['limit']; ++$i)
$projectsCopy[] = $projects[$i];
$projects = $projectsCopy;
}
$tmpl = new Pluf_Template('idf/project-list.html');
$context = new Pluf_Template_Context(array(
'projects' => $projects,
'order' => 'name',
));
return $tmpl->render($context);
} }
} }

View File

@ -46,8 +46,19 @@
{/block} {/block}
{block context} {block context}
{assign $eurl = 'http://michelf.com/projects/php-markdown/extra/'}
{assign $burl = 'http://daringfireball.net/projects/markdown/syntax'}
<div class="issue-submit-info"> <div class="issue-submit-info">
<p>{blocktrans}You can define a custom forge start page that is displayed instead of the standard project listing.{/blocktrans}</p> {blocktrans}
<p><strong>Instructions:</strong></p>
<p>You can set up a custom forge page that is used as entry page for the forge instead of the plain project listing. This page is then also accessible via the 'Home' link in main menu bar.</p>
<p>The content of the page can use the <a href="{$burl}">Markdown syntax</a> with the <a href="{$eurl}"><em>Extra</em> extension</a>.</p>
<p>Additionally, the following macros are available:<br />
<ul>
<li><code>{literal}{{/literal}projectlist, label=..., order=(name|activity), limit=...}</code> - Renders a project list that can optionally be filtered by label, ordered by 'name' or 'activity' and / or limited to a specific number of projects.</li>
</ul>
</p>
{/blocktrans}
</div> </div>
{/block} {/block}

View File

@ -6,7 +6,7 @@
<a href="{url 'IDF_Views::listProjects', array('all', 'name')}" class="active">{trans 'Projects'}</a> <a href="{url 'IDF_Views::listProjects', array('all', 'name')}" class="active">{trans 'Projects'}</a>
{/block} {/block}
{block body} {block body}
{markdown_forge $content} {markdown_forge $content, $request}
{/block} {/block}
{block context}{/block} {block context}{/block}

View File

@ -7,44 +7,7 @@
{aurl 'url', 'IDF_Views_Admin::projectCreate'} {aurl 'url', 'IDF_Views_Admin::projectCreate'}
<p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'Create Project'}</a></p>{/if} <p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'Create Project'}</a></p>{/if}
{else} {else}
{foreach $projects as $p} {include 'idf/project-list.html'}
<div class="p-list-prj">
<div class="logo">
<a href="{url 'IDF_Views_Project::home', array($p.shortname)}">
<img src="{url 'IDF_Views_Project::logo', array($p.shortname)}" alt="{trans 'Project logo'}" />
</a>
{if $p.private}
<div class="private">
<a href="{url 'IDF_Views_Project::home', array($p.shortname)}">
<img style="float:right" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" />
</a>
</div>
{/if}
{if $p.current_activity_value}
{assign $activity = $p.current_activity_value * 100}
<div class="activity" title="{blocktrans}Project activity: {$activity}%{/blocktrans}"><div class="bar" style="width: {$activity}%"></div></div>
{/if}
</div>
<p>
<a href="{url 'IDF_Views_Project::home', array($p.shortname)}"><strong>{$p}</strong></a>
{assign $url = $p.external_project_url}
{if $url != ''}
<a href="{$url}" target="_blank" class="external-link" title="{trans 'External link to project'}" />&nbsp;</a>
{/if}
{if $p.private} - <span class="smaller">{trans 'Private project'}</span>{/if}
</p>
<p class="smaller">{$p.shortdesc}</p>
<p class="smaller">{trans 'Labels:'}
{assign $tags = $p.get_tags_list()}
{if count($tags) == 0}{trans 'n/a'}{else}
{foreach $p.get_tags_list() as $idx => $label}
{if $idx != 0}, {/if}
<a class="label" href="{url 'IDF_Views::listProjectsByLabel', array($label->id, $order)}">{$label}</a>
{/foreach}
{/if}
</p>
</div>
{/foreach}
{/if} {/if}
{/block} {/block}

View File

@ -0,0 +1,41 @@
<div class="p-list">
{foreach $projects as $p}
<div class="p-list-prj">
<div class="logo">
<a href="{url 'IDF_Views_Project::home', array($p.shortname)}">
<img src="{url 'IDF_Views_Project::logo', array($p.shortname)}" alt="{trans 'Project logo'}" />
</a>
{if $p.private}
<div class="private">
<a href="{url 'IDF_Views_Project::home', array($p.shortname)}">
<img style="float:right" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" />
</a>
</div>
{/if}
{if $p.current_activity_value}
{assign $activity = $p.current_activity_value * 100}
<div class="activity" title="{blocktrans}Project activity: {$activity}%{/blocktrans}"><div class="bar" style="width: {$activity}%"></div></div>
{/if}
</div>
<p>
<a href="{url 'IDF_Views_Project::home', array($p.shortname)}"><strong>{$p}</strong></a>
{assign $url = $p.external_project_url}
{if $url != ''}
<a href="{$url}" target="_blank" class="external-link" title="{trans 'External link to project'}" />&nbsp;</a>
{/if}
{if $p.private} - <span class="smaller">{trans 'Private project'}</span>{/if}
</p>
<p class="smaller">{$p.shortdesc}</p>
<p class="smaller">{trans 'Labels:'}
{assign $tags = $p.get_tags_list()}
{if count($tags) == 0}{trans 'n/a'}{else}
{foreach $p.get_tags_list() as $idx => $label}
{if $idx != 0}, {/if}
<a class="label" href="{url 'IDF_Views::listProjectsByLabel', array($label->id, $order)}">{$label}</a>
{/foreach}
{/if}
</p>
</div>
{/foreach}
<div style="clear:both"></div>
</div>