mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-22 19:49:02 +01:00
Make some incremental improvements in Diviner
Summary: Gets TOC populated for articles, at least, and fixes a few other things. Test Plan: {F45474} Reviewers: chad Reviewed By: chad CC: aran Differential Revision: https://secure.phabricator.com/D6144
This commit is contained in:
parent
76c8705a27
commit
1433a035c6
11 changed files with 170 additions and 45 deletions
|
@ -33,7 +33,7 @@ final class DivinerAtomController extends DivinerController {
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$atom = id(new DivinerAtomQuery())
|
||||
$symbol = id(new DivinerAtomQuery())
|
||||
->setViewer($viewer)
|
||||
->withBookPHIDs(array($book->getPHID()))
|
||||
->withTypes(array($this->atomType))
|
||||
|
@ -43,31 +43,91 @@ final class DivinerAtomController extends DivinerController {
|
|||
->needAtoms(true)
|
||||
->executeOne();
|
||||
|
||||
if (!$atom) {
|
||||
if (!$symbol) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$atom = $symbol->getAtom();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName($book->getName())
|
||||
->setName($book->getShortTitle())
|
||||
->setHref('/book/'.$book->getName().'/'));
|
||||
|
||||
$atom_short_title = $atom->getDocblockMetaValue(
|
||||
'short',
|
||||
$symbol->getTitle());
|
||||
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName($atom->getName()));
|
||||
->setName($atom_short_title));
|
||||
|
||||
$header = id(new PhabricatorHeaderView())->setHeader($atom->getName());
|
||||
$header = id(new PhabricatorHeaderView())
|
||||
->setHeader($symbol->getTitle())
|
||||
->addTag(
|
||||
id(new PhabricatorTagView())
|
||||
->setType(PhabricatorTagView::TYPE_STATE)
|
||||
->setBackgroundColor(PhabricatorTagView::COLOR_BLUE)
|
||||
->setName($this->renderAtomTypeName($atom->getType())));
|
||||
|
||||
$properties = id(new PhabricatorPropertyListView());
|
||||
|
||||
$group = $atom->getDocblockMetaValue('group');
|
||||
if ($group) {
|
||||
$group_name = $book->getGroupName($group);
|
||||
} else {
|
||||
$group_name = null;
|
||||
}
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Defined'),
|
||||
$atom->getFile().':'.$atom->getLine());
|
||||
|
||||
$field = 'default';
|
||||
$engine = id(new PhabricatorMarkupEngine())
|
||||
->setViewer($viewer)
|
||||
->addObject($symbol, $field)
|
||||
->process();
|
||||
|
||||
$content = $engine->getOutput($symbol, $field);
|
||||
|
||||
$toc = $engine->getEngineMetadata(
|
||||
$symbol,
|
||||
$field,
|
||||
PhutilRemarkupEngineRemarkupHeaderBlockRule::KEY_HEADER_TOC,
|
||||
array());
|
||||
|
||||
$document = id(new PHUIDocumentView())
|
||||
->setBook($book->getTitle(), $group_name)
|
||||
->setHeader($header)
|
||||
->appendChild($properties)
|
||||
->appendChild(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-remarkup',
|
||||
),
|
||||
phutil_safe_html($atom->getContent())));
|
||||
array(
|
||||
$content,
|
||||
)));
|
||||
|
||||
if ($toc) {
|
||||
$side = new PHUIListView();
|
||||
$side->addMenuItem(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Contents'))
|
||||
->setType(PHUIListItemView::TYPE_LABEL));
|
||||
foreach ($toc as $key => $entry) {
|
||||
$side->addMenuItem(
|
||||
id(new PHUIListItemView())
|
||||
->setName($entry[1])
|
||||
->setHref('#'.$key));
|
||||
}
|
||||
|
||||
$document->setSideNav($side);
|
||||
}
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
|
@ -75,10 +135,14 @@ final class DivinerAtomController extends DivinerController {
|
|||
$document,
|
||||
),
|
||||
array(
|
||||
'title' => $atom->getName(),
|
||||
'title' => $symbol->getTitle(),
|
||||
'dust' => true,
|
||||
'device' => true,
|
||||
));
|
||||
}
|
||||
|
||||
private function renderAtomTypeName($name) {
|
||||
return phutil_utf8_ucwords($name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ final class DivinerBookController extends DivinerController {
|
|||
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName($book->getTitle())
|
||||
->setName($book->getShortTitle())
|
||||
->setHref('/book/'.$book->getName().'/'));
|
||||
|
||||
$header = id(new PhabricatorHeaderView())->setHeader($book->getTitle());
|
||||
|
@ -56,19 +56,7 @@ final class DivinerBookController extends DivinerController {
|
|||
|
||||
$out = array();
|
||||
foreach ($groups as $group => $atoms) {
|
||||
$group_info = idx($group_spec, $group);
|
||||
if (!is_array($group_info)) {
|
||||
$group_info = array();
|
||||
}
|
||||
|
||||
$group_name = idx($group_info, 'name');
|
||||
if (!strlen($group_name)) {
|
||||
if (strlen($group)) {
|
||||
$group_name = $group;
|
||||
} else {
|
||||
$group_name = pht('Free Radicals');
|
||||
}
|
||||
}
|
||||
$group_name = $book->getGroupName($group);
|
||||
|
||||
$out[] = id(new PhabricatorHeaderView())
|
||||
->setHeader($group_name);
|
||||
|
|
|
@ -113,14 +113,12 @@ final class DivinerLivePublisher extends DivinerPublisher {
|
|||
->setGroupName($ref->getGroup());
|
||||
|
||||
if ($is_documentable) {
|
||||
$renderer = $this->getRenderer();
|
||||
$content = $renderer->renderAtom($atom);
|
||||
|
||||
$storage = $this->loadAtomStorageForSymbol($symbol)
|
||||
->setAtomData($atom->toDictionary())
|
||||
->setContent((string)phutil_safe_html($content))
|
||||
->setContent(null)
|
||||
->save();
|
||||
|
||||
$renderer = $this->getRenderer();
|
||||
$summary = $renderer->renderAtomSummary($atom);
|
||||
$summary = (string)phutil_safe_html($summary);
|
||||
$symbol->setSummary($summary);
|
||||
|
|
|
@ -182,12 +182,13 @@ final class DivinerDefaultRenderer extends DivinerRenderer {
|
|||
}
|
||||
|
||||
protected function getBlockMarkupEngine() {
|
||||
$engine = PhabricatorMarkupEngine::newMarkupEngine(
|
||||
array(
|
||||
'preserve-linebreaks' => false,
|
||||
));
|
||||
$engine = PhabricatorMarkupEngine::newMarkupEngine(array());
|
||||
|
||||
$engine->setConfig('preserve-linebreaks', false);
|
||||
$engine->setConfig('viewer', new PhabricatorUser());
|
||||
$engine->setConfig('diviner.renderer', $this);
|
||||
$engine->setConfig('header.generate-toc', true);
|
||||
|
||||
return $engine;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ final class DivinerLiveAtom extends DivinerDAO {
|
|||
return array(
|
||||
self::CONFIG_TIMESTAMPS => false,
|
||||
self::CONFIG_SERIALIZATION => array(
|
||||
'content' => self::SERIALIZATION_JSON,
|
||||
'atomData' => self::SERIALIZATION_JSON,
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
|
|
|
@ -35,6 +35,16 @@ final class DivinerLiveBook extends DivinerDAO
|
|||
return $this->getConfig('title', $this->getName());
|
||||
}
|
||||
|
||||
public function getShortTitle() {
|
||||
return $this->getConfig('short', $this->getTitle());
|
||||
}
|
||||
|
||||
public function getGroupName($group) {
|
||||
$groups = $this->getConfig('groups');
|
||||
$spec = idx($groups, $group, array());
|
||||
return idx($spec, 'name', pht('Free Radicals'));
|
||||
}
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
public function getCapabilities() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DivinerLiveSymbol extends DivinerDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
implements PhabricatorPolicyInterface, PhabricatorMarkupInterface {
|
||||
|
||||
protected $phid;
|
||||
protected $bookPHID;
|
||||
|
@ -18,7 +18,6 @@ final class DivinerLiveSymbol extends DivinerDAO
|
|||
protected $isDocumentable = 0;
|
||||
|
||||
private $book;
|
||||
private $content;
|
||||
private $atom;
|
||||
|
||||
public function getConfiguration() {
|
||||
|
@ -45,13 +44,6 @@ final class DivinerLiveSymbol extends DivinerDAO
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getContent() {
|
||||
if ($this->content === null) {
|
||||
throw new Exception("Call attachAtom() before getContent()!");
|
||||
}
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getAtom() {
|
||||
if ($this->atom === null) {
|
||||
throw new Exception("Call attachAtom() before getAtom()!");
|
||||
|
@ -60,7 +52,6 @@ final class DivinerLiveSymbol extends DivinerDAO
|
|||
}
|
||||
|
||||
public function attachAtom(DivinerLiveAtom $atom) {
|
||||
$this->content = $atom->getContent();
|
||||
$this->atom = DivinerAtom::newFromDictionary($atom->getAtomData());
|
||||
return $this;
|
||||
}
|
||||
|
@ -135,4 +126,41 @@ final class DivinerLiveSymbol extends DivinerDAO
|
|||
return $this->getBook()->hasAutomaticCapability($capability, $viewer);
|
||||
}
|
||||
|
||||
|
||||
/* -( Markup Interface )--------------------------------------------------- */
|
||||
|
||||
|
||||
public function getMarkupFieldKey($field) {
|
||||
return $this->getPHID().':'.$field.':'.$this->getGraphHash();
|
||||
}
|
||||
|
||||
|
||||
public function newMarkupEngine($field) {
|
||||
$engine = PhabricatorMarkupEngine::newMarkupEngine(array());
|
||||
|
||||
$engine->setConfig('preserve-linebreaks', false);
|
||||
// $engine->setConfig('diviner.renderer', new DivinerDefaultRenderer());
|
||||
$engine->setConfig('header.generate-toc', true);
|
||||
|
||||
return $engine;
|
||||
}
|
||||
|
||||
|
||||
public function getMarkupText($field) {
|
||||
return $this->getAtom()->getDocblockText();
|
||||
}
|
||||
|
||||
|
||||
public function didMarkupText(
|
||||
$field,
|
||||
$output,
|
||||
PhutilMarkupEngine $engine) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
public function shouldUseMarkupCache($field) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"name" : "phabricator",
|
||||
"title" : "Phabricator User Documentation",
|
||||
"short" : "Phabricator User Docs",
|
||||
"root" : "../../../",
|
||||
"groups" : {
|
||||
"intro" : {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@title Give Feedback! Get Support!
|
||||
@short Feedback/Support
|
||||
@group intro
|
||||
|
||||
How to give us feedback, report bugs, and request features, and get support for
|
||||
|
|
|
@ -120,15 +120,17 @@ final class PhabricatorMarkupEngine {
|
|||
|
||||
// Load or build the preprocessor caches.
|
||||
$blocks = $this->loadPreprocessorCaches($engines, $objects);
|
||||
$blocks = mpull($blocks, 'getCacheData');
|
||||
|
||||
$this->engineCaches = $blocks;
|
||||
|
||||
// Finalize the output.
|
||||
foreach ($objects as $key => $info) {
|
||||
$data = $blocks[$key]->getCacheData();
|
||||
$engine = $engines[$key];
|
||||
$field = $info['field'];
|
||||
$object = $info['object'];
|
||||
|
||||
$output = $engine->postprocessText($data);
|
||||
$output = $engine->postprocessText($blocks[$key]);
|
||||
$output = $object->didMarkupText($field, $output, $engine);
|
||||
$this->objects[$key]['output'] = $output;
|
||||
}
|
||||
|
@ -149,18 +151,47 @@ final class PhabricatorMarkupEngine {
|
|||
*/
|
||||
public function getOutput(PhabricatorMarkupInterface $object, $field) {
|
||||
$key = $this->getMarkupFieldKey($object, $field);
|
||||
$this->requireKeyProcessed($key);
|
||||
|
||||
return $this->objects[$key]['output'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve engine metadata for a given field.
|
||||
*
|
||||
* @param PhabricatorMarkupInterface The object to retrieve.
|
||||
* @param string The field to retrieve.
|
||||
* @param string The engine metadata field to retrieve.
|
||||
* @param wild Optional default value.
|
||||
* @task markup
|
||||
*/
|
||||
public function getEngineMetadata(
|
||||
PhabricatorMarkupInterface $object,
|
||||
$field,
|
||||
$metadata_key,
|
||||
$default = null) {
|
||||
|
||||
$key = $this->getMarkupFieldKey($object, $field);
|
||||
$this->requireKeyProcessed($key);
|
||||
|
||||
return idx($this->engineCaches[$key]['metadata'], $metadata_key, $default);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task markup
|
||||
*/
|
||||
private function requireKeyProcessed($key) {
|
||||
if (empty($this->objects[$key])) {
|
||||
throw new Exception(
|
||||
"Call addObject() before getOutput() (key = '{$key}').");
|
||||
"Call addObject() before using results (key = '{$key}').");
|
||||
}
|
||||
|
||||
if (!isset($this->objects[$key]['output'])) {
|
||||
throw new Exception(
|
||||
"Call process() before getOutput().");
|
||||
"Call process() before using results.");
|
||||
}
|
||||
|
||||
return $this->objects[$key]['output'];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,11 +21,13 @@ final class PHUIDocumentView extends AphrontTagView {
|
|||
}
|
||||
|
||||
public function setSideNav(PHUIListView $list) {
|
||||
$list->setType(PHUIListView::SIDENAV_LIST);
|
||||
$this->sidenav = $list;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTopNav(PHUIListView $list) {
|
||||
$list->setType(PHUIListView::NAVBAR_LIST);
|
||||
$this->topnav = $list;
|
||||
return $this;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue