Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/phame/application/PhabricatorPhameApplication.php b/src/applications/phame/application/PhabricatorPhameApplication.php
index 16fd83f5b0..f56702ed62 100644
--- a/src/applications/phame/application/PhabricatorPhameApplication.php
+++ b/src/applications/phame/application/PhabricatorPhameApplication.php
@@ -1,126 +1,122 @@
<?php
final class PhabricatorPhameApplication extends PhabricatorApplication {
public function getName() {
return pht('Phame');
}
public function getBaseURI() {
return '/phame/';
}
public function getIcon() {
return 'fa-star';
}
public function getShortDescription() {
return pht('Blog');
}
public function getTitleGlyph() {
return "\xe2\x9c\xa9";
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Phame User Guide'),
'href' => PhabricatorEnv::getDoclink('Phame User Guide'),
),
);
}
- public function isPrototype() {
- return true;
- }
-
public function getRoutes() {
return array(
'/J(?P<id>[1-9]\d*)' => 'PhamePostViewController',
'/phame/' => array(
'' => 'PhameHomeController',
// NOTE: The live routes include an initial "/", so leave it off
// this route.
'(?P<live>live)/(?P<blogID>\d+)' => $this->getLiveRoutes(),
'post/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhamePostListController',
'blogger/(?P<bloggername>[\w\.-_]+)/' => 'PhamePostListController',
$this->getEditRoutePattern('edit/')
=> 'PhamePostEditController',
'history/(?P<id>\d+)/' => 'PhamePostHistoryController',
'view/(?P<id>\d+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
'(?P<action>publish|unpublish)/(?P<id>\d+)/'
=> 'PhamePostPublishController',
'preview/(?P<id>\d+)/' => 'PhamePostPreviewController',
'preview/' => 'PhabricatorMarkupPreviewController',
'move/(?P<id>\d+)/' => 'PhamePostMoveController',
'archive/(?P<id>\d+)/' => 'PhamePostArchiveController',
),
'blog/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhameBlogListController',
'archive/(?P<id>[^/]+)/' => 'PhameBlogArchiveController',
$this->getEditRoutePattern('edit/')
=> 'PhameBlogEditController',
'view/(?P<blogID>\d+)/' => 'PhameBlogViewController',
'manage/(?P<id>[^/]+)/' => 'PhameBlogManageController',
'feed/(?P<id>[^/]+)/' => 'PhameBlogFeedController',
'picture/(?P<id>[1-9]\d*)/' => 'PhameBlogProfilePictureController',
'header/(?P<id>[1-9]\d*)/' => 'PhameBlogHeaderPictureController',
),
) + $this->getResourceSubroutes(),
);
}
public function getResourceRoutes() {
return array(
'/phame/' => $this->getResourceSubroutes(),
);
}
private function getResourceSubroutes() {
return array(
'r/(?P<id>\d+)/(?P<hash>[^/]+)/(?P<name>.*)' =>
'PhameResourceController',
);
}
public function getBlogRoutes() {
return $this->getLiveRoutes();
}
private function getLiveRoutes() {
return array(
'/' => array(
'' => 'PhameBlogViewController',
'post/(?P<id>\d+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
'.*' => 'PhameBlog404Controller',
),
);
}
public function getQuicksandURIPatternBlacklist() {
return array(
'/phame/live/.*',
);
}
public function getRemarkupRules() {
return array(
new PhamePostRemarkupRule(),
);
}
protected function getCustomCapabilities() {
return array(
PhameBlogCreateCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_USER,
'caption' => pht('Default create policy for blogs.'),
),
);
}
}
diff --git a/src/applications/phame/controller/PhameLiveController.php b/src/applications/phame/controller/PhameLiveController.php
index 1287a33f35..2d8b2ee45f 100644
--- a/src/applications/phame/controller/PhameLiveController.php
+++ b/src/applications/phame/controller/PhameLiveController.php
@@ -1,231 +1,233 @@
<?php
abstract class PhameLiveController extends PhameController {
private $isExternal;
private $isLive;
private $blog;
private $post;
public function shouldAllowPublic() {
return true;
}
protected function getIsExternal() {
return $this->isExternal;
}
protected function getIsLive() {
return $this->isLive;
}
protected function getBlog() {
return $this->blog;
}
protected function getPost() {
return $this->post;
}
protected function setupLiveEnvironment() {
$request = $this->getRequest();
$viewer = $this->getViewer();
$site = $request->getSite();
$blog_id = $request->getURIData('blogID');
$post_id = $request->getURIData('id');
if ($site instanceof PhameBlogSite) {
// This is a live page on a custom domain. We already looked up the blog
// in the Site handler by examining the domain, so we don't need to do
// more lookups.
$blog = $site->getBlog();
$is_external = true;
$is_live = true;
} else if ($blog_id) {
// This is a blog detail view, an internal blog live view, or an
// internal post live view The internal post detail view is handled
// below.
$is_external = false;
if ($request->getURIData('live')) {
$is_live = true;
} else {
$is_live = false;
}
$blog_query = id(new PhameBlogQuery())
->setViewer($viewer)
->needProfileImage(true)
->needHeaderImage(true)
->withIDs(array($blog_id));
// If this is a live view, only show active blogs.
if ($is_live) {
$blog_query->withStatuses(
array(
PhameBlog::STATUS_ACTIVE,
));
}
$blog = $blog_query->executeOne();
if (!$blog) {
$this->isExternal = $is_external;
$this->isLive = $is_live;
return new Aphront404Response();
}
} else {
// This is a post detail page, so we'll figure out the blog by loading
// the post first.
$is_external = false;
$is_live = false;
$blog = null;
}
$this->isExternal = $is_external;
$this->isLive = $is_live;
if (strlen($post_id)) {
$post_query = id(new PhamePostQuery())
->setViewer($viewer)
->withIDs(array($post_id));
if ($blog) {
$post_query->withBlogPHIDs(array($blog->getPHID()));
}
// Only show published posts on external domains.
if ($is_external) {
$post_query->withVisibility(
array(PhameConstants::VISIBILITY_PUBLISHED));
}
$post = $post_query->executeOne();
if (!$post) {
// Not a valid Post
$this->blog = $blog;
return new Aphront404Response();
}
// If this is a post detail page, the URI didn't come with a blog ID,
// so fill that in.
if (!$blog) {
$blog = $post->getBlog();
}
} else {
$post = null;
}
$this->blog = $blog;
$this->post = $post;
// If we have a post, canonicalize the URI to the post's current slug and
// redirect the user if it isn't correct.
if ($post) {
$slug = $request->getURIData('slug');
if ($post->getSlug() != $slug) {
if ($is_live) {
if ($is_external) {
$uri = $post->getExternalLiveURI();
} else {
$uri = $post->getInternalLiveURI();
}
} else {
$uri = $post->getViewURI();
}
$response = id(new AphrontRedirectResponse())
->setURI($uri);
if ($is_external) {
$response->setIsExternal(true);
}
return $response;
}
}
return null;
}
protected function buildApplicationCrumbs() {
$blog = $this->getBlog();
$post = $this->getPost();
$is_live = $this->getIsLive();
$is_external = $this->getIsExternal();
// If this is an external view, don't put the "Phame" crumb or the
// "Blogs" crumb into the crumbs list.
if ($is_external) {
$crumbs = new PHUICrumbsView();
// Link back to parent site
if ($blog->getParentSite() && $blog->getParentDomain()) {
$crumbs->addTextCrumb(
$blog->getParentSite(),
$blog->getExternalParentURI());
}
} else {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addTextCrumb(
pht('Blogs'),
$this->getApplicationURI('blog/'));
}
$crumbs->setBorder(true);
if ($blog) {
if ($post) {
if ($is_live) {
if ($is_external) {
$blog_uri = $blog->getExternalLiveURI();
} else {
$blog_uri = $blog->getInternalLiveURI();
}
} else {
$blog_uri = $blog->getViewURI();
}
} else {
$blog_uri = null;
}
$crumbs->addTextCrumb($blog->getName(), $blog_uri);
}
if ($post) {
- $crumbs->addTextCrumb($post->getTitle());
+ if (!$is_external) {
+ $crumbs->addTextCrumb('J'.$post->getID());
+ }
}
return $crumbs;
}
public function willSendResponse(AphrontResponse $response) {
if ($this->getIsExternal()) {
if ($response instanceof Aphront404Response) {
$page = $this->newPage()
->setCrumbs($this->buildApplicationCrumbs());
$response = id(new Phame404Response())
->setPage($page);
}
}
return parent::willSendResponse($response);
}
public function newPage() {
$page = parent::newPage();
if ($this->getIsLive()) {
$page
->addClass('phame-live-view')
->setShowChrome(false)
->setShowFooter(false);
}
return $page;
}
}
diff --git a/src/docs/user/userguide/phame.diviner b/src/docs/user/userguide/phame.diviner
index 0de225c49f..f0f1732c6b 100644
--- a/src/docs/user/userguide/phame.diviner
+++ b/src/docs/user/userguide/phame.diviner
@@ -1,59 +1,65 @@
@title Phame User Guide
@group userguide
-Journal about your thoughts and feelings. Share with others. Profit.
+Phame is an internal and external blogging tool. Use it to communicate both
+internally to your users or externally to others.
= Overview =
-IMPORTANT: Phame is a prototype application.
-
-Phame is a simple blogging platform. You can write drafts which only you can
-see. Later, you can publish these drafts as posts which anyone who can access
-the Phabricator instance can see. You can also add posts to blogs to increase
-your distribution.
+Phame is a simple blogging platform. You can create and own multiple blogs
+for various purposes internal to your organization. We include tools like
+Phame in Phabricator because we believe having a single stack for all
+internal tools is the best way to see they get adopted.
Overall, Phame is intended to help an individual spread their message. As
such, pertinent design decisions skew towards favoring the individual
-rather than the collective.
+rather than the collective. Phame fully integrates with Phabricator on
+key levels such as Feed, Comments, Subscriptions, Policies, and more.
= Drafts =
-Drafts are completely private so draft away.
+By default all new posts are visible unless you set the visibility to
+draft when initially composing. This restricts the post to only members
+with Phame Blog edit privileges. Those members may also see and edit
+the post before it goes live.
= Posts =
-Posts are accessible to anyone who has access to the Phabricator instance.
+Posts are accessible to the individual Phame Blog's view policy. This allows
+you to separate your content according to audience. So you can restrict a
+Engineering Blog to just engineers, or keep contractors out of the Security
+Blog. If you've configured an external blog, all those posts will be publicly
+viewable on publish.
= Blogs =
Blogs are collections of posts. Each blog has associated metadata like
-a name, description, and set of bloggers who can add posts to the blog.
-Each blogger can also edit metadata about the blog and delete the blog
-outright.
+a name, description, and set of bloggers who can add posts to the blog as
+dictated by the blog's edit policy. Each blogger can also edit metadata
+about the blog, the header images, or archive it.
-NOTE: removing a blogger from a given blog does not remove their posts that
+NOTE: Removing a blogger from a given blog does not remove their posts that
are already associated with the blog. Rather, it removes their ability to edit
metadata about and add posts to the blog.
Blogs can be useful for powering external websites, like
blog.yourcompany.com
by making pertinent configuration changes with your DNS authority and
Phabricator instance. For the Phabricator instance, you must
- Enable `policy.allow-public` in Phabricator configuration.
- Configure the blog to have the view policy `public`.
For your DNS authority, simply point the pertinent domain name at your
Phabricator instance. e.g. by IP address.
-= Comment Widgets =
+There are three fields to know about when setting up a blog for external use.
-Phame supports comment widgets from Facebook and Disqus. The administrator
-of the Phabricator instance must properly configure Phabricator to enable
-this functionality.
+ - **Full Domain URI:** Set this to the full URI you intend to serve the Phame
+ blog from.
+ - **Parent Site Name/URI:** Phame serves Blogs with a very minimal UI.
+ To help provide some context and navigation, these field may be set to give
+ users a way back to the parent site the blog was originally linked from.
-A given comment widget is tied 1:1 with a given post. This means the same
-instance of a given comment widget will appear for a given post regardless
-of whether that post is being viewed in the context of a blog.

File Metadata

Mime Type
text/x-diff
Expires
Fri, Mar 14, 7:07 AM (3 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71660
Default Alt Text
(14 KB)

Event Timeline