1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-23 12:09:12 +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:
epriestley 2013-06-06 08:36:51 -07:00
parent 76c8705a27
commit 1433a035c6
11 changed files with 170 additions and 45 deletions

View file

@ -33,7 +33,7 @@ final class DivinerAtomController extends DivinerController {
return new Aphront404Response(); return new Aphront404Response();
} }
$atom = id(new DivinerAtomQuery()) $symbol = id(new DivinerAtomQuery())
->setViewer($viewer) ->setViewer($viewer)
->withBookPHIDs(array($book->getPHID())) ->withBookPHIDs(array($book->getPHID()))
->withTypes(array($this->atomType)) ->withTypes(array($this->atomType))
@ -43,31 +43,91 @@ final class DivinerAtomController extends DivinerController {
->needAtoms(true) ->needAtoms(true)
->executeOne(); ->executeOne();
if (!$atom) { if (!$symbol) {
return new Aphront404Response(); return new Aphront404Response();
} }
$atom = $symbol->getAtom();
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb( $crumbs->addCrumb(
id(new PhabricatorCrumbView()) id(new PhabricatorCrumbView())
->setName($book->getName()) ->setName($book->getShortTitle())
->setHref('/book/'.$book->getName().'/')); ->setHref('/book/'.$book->getName().'/'));
$atom_short_title = $atom->getDocblockMetaValue(
'short',
$symbol->getTitle());
$crumbs->addCrumb( $crumbs->addCrumb(
id(new PhabricatorCrumbView()) 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()) $document = id(new PHUIDocumentView())
->setBook($book->getTitle(), $group_name)
->setHeader($header)
->appendChild($properties)
->appendChild( ->appendChild(
phutil_tag( phutil_tag(
'div', 'div',
array( array(
'class' => 'phabricator-remarkup', '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( return $this->buildApplicationPage(
array( array(
@ -75,10 +135,14 @@ final class DivinerAtomController extends DivinerController {
$document, $document,
), ),
array( array(
'title' => $atom->getName(), 'title' => $symbol->getTitle(),
'dust' => true, 'dust' => true,
'device' => true, 'device' => true,
)); ));
} }
private function renderAtomTypeName($name) {
return phutil_utf8_ucwords($name);
}
} }

View file

@ -29,7 +29,7 @@ final class DivinerBookController extends DivinerController {
$crumbs->addCrumb( $crumbs->addCrumb(
id(new PhabricatorCrumbView()) id(new PhabricatorCrumbView())
->setName($book->getTitle()) ->setName($book->getShortTitle())
->setHref('/book/'.$book->getName().'/')); ->setHref('/book/'.$book->getName().'/'));
$header = id(new PhabricatorHeaderView())->setHeader($book->getTitle()); $header = id(new PhabricatorHeaderView())->setHeader($book->getTitle());
@ -56,19 +56,7 @@ final class DivinerBookController extends DivinerController {
$out = array(); $out = array();
foreach ($groups as $group => $atoms) { foreach ($groups as $group => $atoms) {
$group_info = idx($group_spec, $group); $group_name = $book->getGroupName($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');
}
}
$out[] = id(new PhabricatorHeaderView()) $out[] = id(new PhabricatorHeaderView())
->setHeader($group_name); ->setHeader($group_name);

View file

@ -113,14 +113,12 @@ final class DivinerLivePublisher extends DivinerPublisher {
->setGroupName($ref->getGroup()); ->setGroupName($ref->getGroup());
if ($is_documentable) { if ($is_documentable) {
$renderer = $this->getRenderer();
$content = $renderer->renderAtom($atom);
$storage = $this->loadAtomStorageForSymbol($symbol) $storage = $this->loadAtomStorageForSymbol($symbol)
->setAtomData($atom->toDictionary()) ->setAtomData($atom->toDictionary())
->setContent((string)phutil_safe_html($content)) ->setContent(null)
->save(); ->save();
$renderer = $this->getRenderer();
$summary = $renderer->renderAtomSummary($atom); $summary = $renderer->renderAtomSummary($atom);
$summary = (string)phutil_safe_html($summary); $summary = (string)phutil_safe_html($summary);
$symbol->setSummary($summary); $symbol->setSummary($summary);

View file

@ -182,12 +182,13 @@ final class DivinerDefaultRenderer extends DivinerRenderer {
} }
protected function getBlockMarkupEngine() { protected function getBlockMarkupEngine() {
$engine = PhabricatorMarkupEngine::newMarkupEngine( $engine = PhabricatorMarkupEngine::newMarkupEngine(array());
array(
'preserve-linebreaks' => false, $engine->setConfig('preserve-linebreaks', false);
));
$engine->setConfig('viewer', new PhabricatorUser()); $engine->setConfig('viewer', new PhabricatorUser());
$engine->setConfig('diviner.renderer', $this); $engine->setConfig('diviner.renderer', $this);
$engine->setConfig('header.generate-toc', true);
return $engine; return $engine;
} }

View file

@ -10,6 +10,7 @@ final class DivinerLiveAtom extends DivinerDAO {
return array( return array(
self::CONFIG_TIMESTAMPS => false, self::CONFIG_TIMESTAMPS => false,
self::CONFIG_SERIALIZATION => array( self::CONFIG_SERIALIZATION => array(
'content' => self::SERIALIZATION_JSON,
'atomData' => self::SERIALIZATION_JSON, 'atomData' => self::SERIALIZATION_JSON,
), ),
) + parent::getConfiguration(); ) + parent::getConfiguration();

View file

@ -35,6 +35,16 @@ final class DivinerLiveBook extends DivinerDAO
return $this->getConfig('title', $this->getName()); 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 )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() { public function getCapabilities() {

View file

@ -1,7 +1,7 @@
<?php <?php
final class DivinerLiveSymbol extends DivinerDAO final class DivinerLiveSymbol extends DivinerDAO
implements PhabricatorPolicyInterface { implements PhabricatorPolicyInterface, PhabricatorMarkupInterface {
protected $phid; protected $phid;
protected $bookPHID; protected $bookPHID;
@ -18,7 +18,6 @@ final class DivinerLiveSymbol extends DivinerDAO
protected $isDocumentable = 0; protected $isDocumentable = 0;
private $book; private $book;
private $content;
private $atom; private $atom;
public function getConfiguration() { public function getConfiguration() {
@ -45,13 +44,6 @@ final class DivinerLiveSymbol extends DivinerDAO
return $this; return $this;
} }
public function getContent() {
if ($this->content === null) {
throw new Exception("Call attachAtom() before getContent()!");
}
return $this->content;
}
public function getAtom() { public function getAtom() {
if ($this->atom === null) { if ($this->atom === null) {
throw new Exception("Call attachAtom() before getAtom()!"); throw new Exception("Call attachAtom() before getAtom()!");
@ -60,7 +52,6 @@ final class DivinerLiveSymbol extends DivinerDAO
} }
public function attachAtom(DivinerLiveAtom $atom) { public function attachAtom(DivinerLiveAtom $atom) {
$this->content = $atom->getContent();
$this->atom = DivinerAtom::newFromDictionary($atom->getAtomData()); $this->atom = DivinerAtom::newFromDictionary($atom->getAtomData());
return $this; return $this;
} }
@ -135,4 +126,41 @@ final class DivinerLiveSymbol extends DivinerDAO
return $this->getBook()->hasAutomaticCapability($capability, $viewer); 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;
}
} }

View file

@ -1,6 +1,7 @@
{ {
"name" : "phabricator", "name" : "phabricator",
"title" : "Phabricator User Documentation", "title" : "Phabricator User Documentation",
"short" : "Phabricator User Docs",
"root" : "../../../", "root" : "../../../",
"groups" : { "groups" : {
"intro" : { "intro" : {

View file

@ -1,4 +1,5 @@
@title Give Feedback! Get Support! @title Give Feedback! Get Support!
@short Feedback/Support
@group intro @group intro
How to give us feedback, report bugs, and request features, and get support for How to give us feedback, report bugs, and request features, and get support for

View file

@ -120,15 +120,17 @@ final class PhabricatorMarkupEngine {
// Load or build the preprocessor caches. // Load or build the preprocessor caches.
$blocks = $this->loadPreprocessorCaches($engines, $objects); $blocks = $this->loadPreprocessorCaches($engines, $objects);
$blocks = mpull($blocks, 'getCacheData');
$this->engineCaches = $blocks;
// Finalize the output. // Finalize the output.
foreach ($objects as $key => $info) { foreach ($objects as $key => $info) {
$data = $blocks[$key]->getCacheData();
$engine = $engines[$key]; $engine = $engines[$key];
$field = $info['field']; $field = $info['field'];
$object = $info['object']; $object = $info['object'];
$output = $engine->postprocessText($data); $output = $engine->postprocessText($blocks[$key]);
$output = $object->didMarkupText($field, $output, $engine); $output = $object->didMarkupText($field, $output, $engine);
$this->objects[$key]['output'] = $output; $this->objects[$key]['output'] = $output;
} }
@ -149,18 +151,47 @@ final class PhabricatorMarkupEngine {
*/ */
public function getOutput(PhabricatorMarkupInterface $object, $field) { public function getOutput(PhabricatorMarkupInterface $object, $field) {
$key = $this->getMarkupFieldKey($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])) { if (empty($this->objects[$key])) {
throw new Exception( throw new Exception(
"Call addObject() before getOutput() (key = '{$key}')."); "Call addObject() before using results (key = '{$key}').");
} }
if (!isset($this->objects[$key]['output'])) { if (!isset($this->objects[$key]['output'])) {
throw new Exception( throw new Exception(
"Call process() before getOutput()."); "Call process() before using results.");
} }
return $this->objects[$key]['output'];
} }

View file

@ -21,11 +21,13 @@ final class PHUIDocumentView extends AphrontTagView {
} }
public function setSideNav(PHUIListView $list) { public function setSideNav(PHUIListView $list) {
$list->setType(PHUIListView::SIDENAV_LIST);
$this->sidenav = $list; $this->sidenav = $list;
return $this; return $this;
} }
public function setTopNav(PHUIListView $list) { public function setTopNav(PHUIListView $list) {
$list->setType(PHUIListView::NAVBAR_LIST);
$this->topnav = $list; $this->topnav = $list;
return $this; return $this;
} }