diff --git a/externals/skins/oblivious/css/oblivious.css b/externals/skins/oblivious/css/oblivious.css index cad5d6cf9..044d478aa 100644 --- a/externals/skins/oblivious/css/oblivious.css +++ b/externals/skins/oblivious/css/oblivious.css @@ -1,90 +1,76 @@ html, body, p, h1, h2, h3 { padding: 0; margin: 0; font-weight: normal; } html { font-family: "Helvetica Neue", "Arial", sans-serif; font-size: 16px; overflow-y: scroll; color: #555555; } .oblivious-info { position: fixed; width: 15%; border-right: 1px solid #dfdfdf; top: 0; bottom: 0; left: 0; padding: 140px 2% 0; overflow: hidden; background: url(/image/badge.png); background-repeat: no-repeat; background-position: 20px 20px; } .oblivious-content { padding-top: 3%; margin-left: 22%; - max-width: 600px; + max-width: 800px; } a { - color: #222222; + color: #2980b9; text-decoration: none; } a:hover { - color: #a00000; + text-decoration: underline; } - h1 { font-size: 24px; font-weight: normal; } h2 { font-size: 22px; font-weight: bold; + margin-bottom: 8px; } .phame-post { margin: 0 0 2em; } -.phame-post-date { - font-size: 12px; - margin: .25em 0 1em; -} - -.phame-post { - line-height: 1.6em; -} - -.phame-post p { - margin: 0 0 1em; +.phame-post-title { + font-size: 28px; } -.phame-post tt { - color: #333333; - background: #ebebeb; - padding: 0 .25em; - white-space: pre-wrap; +.phame-post-date { + font-size: 12px; + margin: .25em 0 2em; } -.phame-post .remarkup-code-block pre { - overflow: auto; - padding: 10px 10px; - border: 1px solid #dfdfdf; - background-color: #f8f8f8; +.oblivious-content .phabricator-remarkup ul.remarkup-list { + margin-left: 0; } .fb-comments, .fb-comments span, .fb-comments iframe[style] { width: 100% !important; } diff --git a/src/applications/phame/skins/PhameBasicBlogSkin.php b/src/applications/phame/skins/PhameBasicBlogSkin.php index efaa85ec8..5ba8d0999 100644 --- a/src/applications/phame/skins/PhameBasicBlogSkin.php +++ b/src/applications/phame/skins/PhameBasicBlogSkin.php @@ -1,324 +1,325 @@ uriPath = $uri_path; return $this; } + public function getURIPath() { return $this->uriPath; } protected function setOGType($og_type) { $this->oGType = $og_type; return $this; } + protected function getOGType() { return $this->oGType; } protected function setDescription($description) { $this->description = $description; return $this; } + protected function getDescription() { return $this->description; } protected function setTitle($title) { $this->title = $title; return $this; } + protected function getTitle() { return $this->title; } - public function processRequest() { - $request = $this->getRequest(); - + public function handleRequest(AphrontRequest $request) { $content = $this->renderContent($request); if (!$content) { $content = $this->render404Page(); } $content = array( $this->renderHeader(), $content, $this->renderFooter(), ); $view = id(new PhabricatorBarePageView()) ->setRequest($request) ->setController($this) ->setDeviceReady(true) ->setTitle($this->getBlog()->getName()); if ($this->getPreview()) { $view->setFrameable(true); } - $view->appendChild($content); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } public function getSkinName() { return get_class($this); } abstract protected function renderHeader(); abstract protected function renderFooter(); protected function renderPostDetail(PhamePostView $post) { return $post; } protected function renderPostList(array $posts) { $summaries = array(); foreach ($posts as $post) { $summaries[] = $post->renderWithSummary(); } $list = phutil_tag( 'div', array( 'class' => 'phame-post-list', ), id(new AphrontNullView())->appendChild($summaries)->render()); $pager = null; if ($this->renderOlderPageLink() || $this->renderNewerPageLink()) { $pager = phutil_tag( 'div', array( 'class' => 'phame-pager', ), array( $this->renderOlderPageLink(), $this->renderNewerPageLink(), )); } return array( $list, $pager, ); } protected function render404Page() { return phutil_tag('h2', array(), pht('404 Not Found')); } final public function getResourceURI($resource) { $root = $this->getSpecification()->getRootDirectory(); $path = $root.DIRECTORY_SEPARATOR.$resource; $data = Filesystem::readFile($path); $hash = PhabricatorHash::digest($data); $hash = substr($hash, 0, 6); $id = $this->getBlog()->getID(); $uri = '/phame/r/'.$id.'/'.$hash.'/'.$resource; $uri = PhabricatorEnv::getCDNURI($uri); return $uri; } /* -( Paging )------------------------------------------------------------- */ /** * @task paging */ public function getPageSize() { return 100; } /** * @task paging */ protected function getOlderPageURI() { if ($this->pager) { $next = $this->pager->getNextPageID(); if ($next) { return $this->getURI('older/'.$next.'/'); } } return null; } /** * @task paging */ protected function renderOlderPageLink() { $uri = $this->getOlderPageURI(); if (!$uri) { return null; } return phutil_tag( 'a', array( 'class' => 'phame-page-link phame-page-older', 'href' => $uri, ), pht("\xE2\x80\xB9 Older")); } /** * @task paging */ protected function getNewerPageURI() { if ($this->pager) { $next = $this->pager->getPrevPageID(); if ($next) { return $this->getURI('newer/'.$next.'/'); } } return null; } /** * @task paging */ protected function renderNewerPageLink() { $uri = $this->getNewerPageURI(); if (!$uri) { return null; } return phutil_tag( 'a', array( 'class' => 'phame-page-link phame-page-newer', 'href' => $uri, ), pht("Newer \xE2\x80\xBA")); } /* -( Internals )---------------------------------------------------------- */ /** * @task internal */ protected function renderContent(AphrontRequest $request) { - $user = $request->getUser(); + $viewer = $request->getViewer(); $matches = null; $path = $request->getPath(); // default to the blog-wide values $this->setTitle($this->getBlog()->getName()); $this->setDescription($this->getBlog()->getDescription()); $this->setOGType('website'); $this->setURIPath(''); if (preg_match('@^/post/(?P.*)$@', $path, $matches)) { $post = id(new PhamePostQuery()) - ->setViewer($user) + ->setViewer($viewer) ->withBlogPHIDs(array($this->getBlog()->getPHID())) ->withPhameTitles(array($matches['name'])) ->executeOne(); if ($post) { $description = $post->getMarkupText(PhamePost::MARKUP_FIELD_SUMMARY); $this->setTitle($post->getTitle()); $this->setDescription($description); $this->setOGType('article'); $this->setURIPath('post/'.$post->getPhameTitle()); $view = head($this->buildPostViews(array($post))); return $this->renderPostDetail($view); } } else { $pager = new AphrontCursorPagerView(); if (preg_match('@^/older/(?P\d+)/$@', $path, $matches)) { $pager->setAfterID($matches['before']); } else if (preg_match('@^/newer/(?P\d)/$@', $path, $matches)) { $pager->setBeforeID($matches['after']); } else if (preg_match('@^/$@', $path, $matches)) { // Just show the first page. } else { return null; } $pager->setPageSize($this->getPageSize()); $posts = id(new PhamePostQuery()) - ->setViewer($user) + ->setViewer($viewer) ->withBlogPHIDs(array($this->getBlog()->getPHID())) ->executeWithCursorPager($pager); $this->pager = $pager; if ($posts) { $views = $this->buildPostViews($posts); return $this->renderPostList($views); } } return null; } private function buildPostViews(array $posts) { assert_instances_of($posts, 'PhamePost'); - $user = $this->getRequest()->getUser(); + $viewer = $this->getViewer(); $engine = id(new PhabricatorMarkupEngine()) - ->setViewer($user); + ->setViewer($viewer); $phids = array(); foreach ($posts as $post) { $engine->addObject($post, PhamePost::MARKUP_FIELD_BODY); $engine->addObject($post, PhamePost::MARKUP_FIELD_SUMMARY); $phids[] = $post->getBloggerPHID(); } $handles = id(new PhabricatorHandleQuery()) - ->setViewer($user) + ->setViewer($viewer) ->withPHIDs($phids) ->execute(); $engine->process(); $views = array(); foreach ($posts as $post) { $view = id(new PhamePostView()) - ->setUser($user) + ->setUser($viewer) ->setSkin($this) ->setPost($post) ->setBody($engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY)) ->setSummary($engine->getOutput($post, PhamePost::MARKUP_FIELD_SUMMARY)) ->setAuthor($handles[$post->getBloggerPHID()]); $post->makeEphemeral(); if (!$post->getDatePublished()) { $post->setDatePublished(time()); } $views[] = $view; } return $views; } } diff --git a/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php b/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php index 5b4c802c6..ba5c479f2 100644 --- a/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php +++ b/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php @@ -1,141 +1,152 @@ cssResources = array(); $css = $this->getPath('css/'); if (Filesystem::pathExists($css)) { foreach (Filesystem::listDirectory($css) as $path) { if (!preg_match('/.css$/', $path)) { continue; } $this->cssResources[] = phutil_tag( 'link', array( 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getResourceURI('css/'.$path), )); } } $map = CelerityResourceMap::getNamedInstance('phabricator'); - $resource_symbol = 'syntax-highlighting-css'; - $resource_uri = $map->getURIForSymbol($resource_symbol); + $highlight_symbol = 'syntax-highlighting-css'; + $highlight_uri = $map->getURIForSymbol($highlight_symbol); $this->cssResources[] = phutil_tag( 'link', array( 'rel' => 'stylesheet', 'type' => 'text/css', - 'href' => PhabricatorEnv::getCDNURI($resource_uri), + 'href' => PhabricatorEnv::getCDNURI($highlight_uri), + )); + + $remarkup_symbol = 'phabricator-remarkup-css'; + $remarkup_uri = $map->getURIForSymbol($remarkup_symbol); + + $this->cssResources[] = phutil_tag( + 'link', + array( + 'rel' => 'stylesheet', + 'type' => 'text/css', + 'href' => PhabricatorEnv::getCDNURI($remarkup_uri), )); $this->cssResources = phutil_implode_html("\n", $this->cssResources); $request = $this->getRequest(); // Render page parts in order so the templates execute in order, if we're // using templates. $header = $this->renderHeader(); $content = $this->renderContent($request); $footer = $this->renderFooter(); if (!$content) { $content = $this->render404Page(); } $content = array( $header, $content, $footer, ); $response = new AphrontWebpageResponse(); $response->setContent(phutil_implode_html("\n", $content)); return $response; } public function getCSSResources() { return $this->cssResources; } public function getName() { return $this->getSpecification()->getName(); } public function getPath($to_file = null) { $path = $this->getSpecification()->getRootDirectory(); if ($to_file) { $path = $path.DIRECTORY_SEPARATOR.$to_file; } return $path; } private function renderTemplate($__template__, array $__scope__) { chdir($this->getPath()); ob_start(); if (Filesystem::pathExists($this->getPath($__template__))) { // Fool lint. $__evil__ = 'extract'; $__evil__($__scope__ + $this->getDefaultScope()); require $this->getPath($__template__); } return phutil_safe_html(ob_get_clean()); } private function getDefaultScope() { return array( 'skin' => $this, 'blog' => $this->getBlog(), 'uri' => $this->getURI($this->getURIPath()), 'home_uri' => $this->getURI(''), 'title' => $this->getTitle(), 'description' => $this->getDescription(), 'og_type' => $this->getOGType(), ); } protected function renderHeader() { return $this->renderTemplate( 'header.php', array()); } protected function renderFooter() { return $this->renderTemplate('footer.php', array()); } protected function render404Page() { return $this->renderTemplate('404.php', array()); } protected function renderPostDetail(PhamePostView $post) { return $this->renderTemplate( 'post-detail.php', array( 'post' => $post, )); } protected function renderPostList(array $posts) { return $this->renderTemplate( 'post-list.php', array( 'posts' => $posts, 'older' => $this->renderOlderPageLink(), 'newer' => $this->renderNewerPageLink(), )); } } diff --git a/src/applications/phame/view/PhamePostView.php b/src/applications/phame/view/PhamePostView.php index f35125f25..9fef145e0 100644 --- a/src/applications/phame/view/PhamePostView.php +++ b/src/applications/phame/view/PhamePostView.php @@ -1,241 +1,241 @@ skin = $skin; return $this; } public function getSkin() { return $this->skin; } public function setAuthor(PhabricatorObjectHandle $author) { $this->author = $author; return $this; } public function getAuthor() { return $this->author; } public function setPost(PhamePost $post) { $this->post = $post; return $this; } public function getPost() { return $this->post; } public function setBody($body) { $this->body = $body; return $this; } public function getBody() { return $this->body; } public function setSummary($summary) { $this->summary = $summary; return $this; } public function getSummary() { return $this->summary; } public function renderTitle() { $href = $this->getSkin()->getURI('post/'.$this->getPost()->getPhameTitle()); return phutil_tag( 'h2', array( 'class' => 'phame-post-title', ), phutil_tag( 'a', array( 'href' => $href, ), $this->getPost()->getTitle())); } public function renderDatePublished() { return phutil_tag( 'div', array( 'class' => 'phame-post-date', ), pht( 'Published on %s by %s', phabricator_datetime( $this->getPost()->getDatePublished(), $this->getUser()), $this->getAuthor()->getName())); } public function renderBody() { return phutil_tag( 'div', array( - 'class' => 'phame-post-body', + 'class' => 'phame-post-body phabricator-remarkup', ), $this->getBody()); } public function renderSummary() { return phutil_tag( 'div', array( - 'class' => 'phame-post-body', + 'class' => 'phame-post-body phabricator-remarkup', ), $this->getSummary()); } public function renderComments() { $post = $this->getPost(); switch ($post->getCommentsWidget()) { case 'facebook': $comments = $this->renderFacebookComments(); break; case 'disqus': $comments = $this->renderDisqusComments(); break; case 'none': default: $comments = null; break; } return $comments; } public function render() { return phutil_tag( 'div', array( 'class' => 'phame-post', ), array( $this->renderTitle(), $this->renderDatePublished(), $this->renderBody(), $this->renderComments(), )); } public function renderWithSummary() { return phutil_tag( 'div', array( 'class' => 'phame-post', ), array( $this->renderTitle(), $this->renderDatePublished(), $this->renderSummary(), )); } private function renderFacebookComments() { $fb_id = PhabricatorFacebookAuthProvider::getFacebookApplicationID(); if (!$fb_id) { return null; } $fb_root = phutil_tag('div', array( 'id' => 'fb-root', ), ''); $c_uri = '//connect.facebook.net/en_US/all.js#xfbml=1&appId='.$fb_id; $fb_js = CelerityStaticResourceResponse::renderInlineScript( jsprintf( '(function(d, s, id) {'. ' var js, fjs = d.getElementsByTagName(s)[0];'. ' if (d.getElementById(id)) return;'. ' js = d.createElement(s); js.id = id;'. ' js.src = %s;'. ' fjs.parentNode.insertBefore(js, fjs);'. '}(document, \'script\', \'facebook-jssdk\'));', $c_uri)); $uri = $this->getSkin()->getURI('post/'.$this->getPost()->getPhameTitle()); require_celerity_resource('phame-css'); $fb_comments = phutil_tag('div', array( 'class' => 'fb-comments', 'data-href' => $uri, 'data-num-posts' => 5, ), ''); return phutil_tag( 'div', array( 'class' => 'phame-comments-facebook', ), array( $fb_root, $fb_js, $fb_comments, )); } private function renderDisqusComments() { $disqus_shortname = PhabricatorEnv::getEnvConfig('disqus.shortname'); if (!$disqus_shortname) { return null; } $post = $this->getPost(); $disqus_thread = phutil_tag('div', array( 'id' => 'disqus_thread', )); // protip - try some var disqus_developer = 1; action to test locally $disqus_js = CelerityStaticResourceResponse::renderInlineScript( jsprintf( ' var disqus_shortname = %s;'. ' var disqus_identifier = %s;'. ' var disqus_url = %s;'. ' var disqus_title = %s;'. '(function() {'. ' var dsq = document.createElement("script");'. ' dsq.type = "text/javascript";'. ' dsq.async = true;'. ' dsq.src = "//" + disqus_shortname + ".disqus.com/embed.js";'. '(document.getElementsByTagName("head")[0] ||'. ' document.getElementsByTagName("body")[0]).appendChild(dsq);'. '})();', $disqus_shortname, $post->getPHID(), $this->getSkin()->getURI('post/'.$this->getPost()->getPhameTitle()), $post->getTitle())); return phutil_tag( 'div', array( 'class' => 'phame-comments-disqus', ), array( $disqus_thread, $disqus_js, )); } }