Added blog type dropdown to gridfield

This commit is contained in:
micmania1 2013-08-04 17:38:26 +01:00
parent 2201af5c74
commit b077e587df
31 changed files with 879 additions and 179 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.ssh/*
.bash*
.profile
vendor/*

View File

@ -1 +1,21 @@
<?php <?php
/**
* Fetches the name of the current module folder name.
*
* @return string
**/
function blog_dir() {
return trim(str_replace(BASE_PATH, "", dirname(__FILE__)), DIRECTORY_SEPARATOR);
}
/**
* Returns the absolute path of the current module path
*
* @return string
**/
function blog_path() {
return BASE_PATH . '/' . blog_dir();
}

View File

@ -1,6 +1,7 @@
--- ---
Name: silverstripe-blog Only:
moduleexists: 'widgets'
--- ---
Blog: BlogPost:
extensions: defaults:
- 'BlogPostFilter' 'InheritSideBar': true

9
css/cms.css Executable file
View File

@ -0,0 +1,9 @@
.cms .ss-gridfield .gridfield-dropdown {
margin: 3px 8px 0 0;
border-bottom: none;
}
.cms .ss-gridfield .gridfield-dropdown .chzn-container,
.cms .ss-gridfield .gridfield-dropdown .dropdown {
min-width: 195px;
}

65
extensions/BlogFilter.php Executable file
View File

@ -0,0 +1,65 @@
<?php
/**
* Base extension of BlogPost.
*
* @package silverstripe
* @subpackage blog
*
* @author Michael Strong <micmania@hotmail.co.uk>
*
**/
class BlogFilter extends Hierarchy {
/**
* Augments (@link Hierarchy::stageChildren()}
*
* @param $staged DataList
* @param $showAll boolean
**/
public function stageChildren($showAll = false) {
$staged = parent::stageChildren($showAll);
$controller = Controller::curr();
if($controller->class == "CMSPagesController" && in_array($controller->getAction(), array("treeview", "listview", "getsubtree"))) {
return $staged->exclude("ClassName", $this->owner->getExcludedSiteTreeClassNames());
} else if(in_array($this->owner->ClassName, ClassInfo::subClassesFor("Blog")) && !Permission::check("VIEW_DRAFT_CONTENT")) {
// Get the current stage.
$stage = Versioned::current_stage();
if($stage == "Stage") $stage = "";
else $stage = "_" . Convert::raw2sql($stage);
$dataQuery = $staged->dataQuery()
->innerJoin("BlogPost", "BlogPost" . $stage . ".ID = SiteTree" . $stage . ".ID")
->where("PublishDate < NOW()");
$staged = $staged->setDataQuery($dataQuery);
}
return $staged;
}
/**
* Augments (@link Hierarchy::liveChildren()}
*
* @param $staged DataList
* @param $showAll boolean
**/
public function liveChildren($showAll = false, $onlyDeletedFromStage = false) {
$staged = parent::liveChildren($showAll, $onlyDeletedFromStage);
$controller = Controller::curr();
if($controller->class == "CMSPagesController" && in_array($controller->getAction(), array("treeview", "listview", "getsubtree"))) {
return $staged->exclude("ClassName", $this->owner->getExcludedSiteTreeClassNames());
} else if(in_array($this->owner->ClassName, ClassInfo::subClassesFor("Blog")) && !Permission::check("VIEW_DRAFT_CONTENT")) {
$dataQuery = $staged->dataQuery()
->innerJoin("BlogPost", "BlogPost_Live.ID = SiteTree_Live.ID")
->where("PublishDate < NOW()");
$staged = $staged->setDataQuery($dataQuery);
}
return $staged;
}
}

View File

@ -1,65 +1,18 @@
<?php <?php
/** class BlogPostFilter extends DataExtension {
* Base extension of BlogPost.
*
* @package silverstripe
* @subpackage blog
*
* @author Michael Strong <micmania@hotmail.co.uk>
*
**/
class BlogPostFilter extends Hierarchy {
/** /**
* Augments (@link Hierarchy::stageChildren()} * Augment queries so that we don't fetch unpublished articles.
*
* @param $staged DataList
* @param $showAll boolean
**/ **/
public function stageChildren($showAll = false) { public function augmentSQL(SQLQuery &$query) {
$staged = parent::stageChildren($showAll);
$controller = Controller::curr();
if($controller->class == "CMSPagesController" && in_array($controller->getAction(), array("treeview", "listview", "getsubtree"))) {
return $staged->exclude("ClassName", $this->owner->getExcludedSiteTreeClassNames());
} else if(in_array($this->owner->ClassName, ClassInfo::subClassesFor("Blog")) && !Permission::check("VIEW_DRAFT_CONTENT")) {
// Get the current stage.
$stage = Versioned::current_stage(); $stage = Versioned::current_stage();
if($stage == "Stage") $stage = ""; if($stage == "Stage") $stage = "";
else $stage = "_" . Convert::raw2sql($stage); else $stage = "_" . Convert::raw2sql($stage);
$dataQuery = $staged->dataQuery() $query->addWhere("PublishDate < NOW()");
->innerJoin("BlogPost", "BlogPost" . $stage . ".ID = SiteTree" . $stage . ".ID")
->where("PublishDate < NOW()");
$staged = $staged->setDataQuery($dataQuery);
} }
return $staged;
}
/**
* Augments (@link Hierarchy::liveChildren()}
*
* @param $staged DataList
* @param $showAll boolean
**/
public function liveChildren($showAll = false, $onlyDeletedFromStage = false) {
$staged = parent::liveChildren($showAll, $onlyDeletedFromStage);
$controller = Controller::curr();
if($controller->class == "CMSPagesController" && in_array($controller->getAction(), array("treeview", "listview", "getsubtree"))) {
return $staged->exclude("ClassName", $this->owner->getExcludedSiteTreeClassNames());
} else if(in_array($this->owner->ClassName, ClassInfo::subClassesFor("Blog")) && !Permission::check("VIEW_DRAFT_CONTENT")) {
$dataQuery = $staged->dataQuery()
->innerJoin("BlogPost", "BlogPost_Live.ID = SiteTree_Live.ID")
->where("PublishDate < NOW()");
$staged = $staged->setDataQuery($dataQuery);
}
return $staged;
}
} }

View File

@ -0,0 +1,48 @@
<?php
/**
* Adds URLSegment functionality to Tags & Categories
*
* @package silverstripe
* @subpackage blog
*
* @author Michael Strong <micmania@hotmail.co.uk>
**/
class URLSegmentExtension extends DataExtension {
private static $db = array(
"URLSegment" => "Varchar(255)"
);
public function onBeforeWrite() {
$this->owner->generateURLSegment();
}
/**
* Generates a unique URLSegment from the title.
*
* @param $increment
*
* @return string URLSegment
**/
public function generateURLSegment($increment = null) {
$filter = new URLSegmentFilter();
$this->owner->URLSegment = $filter->filter($this->owner->Title);
if(is_int($increment)) $this->owner->URLSegment .= '-' . $increment;
// Check to see if the URLSegment already exists
$duplicate = DataList::create($this->owner->ClassName)->filter(array(
"URLSegment" => $this->owner->URLSegment,
"BlogID" => $this->owner->BlogID
));
if($this->owner->ID) $duplicate = $duplicate->exclude("ID", $this->owner->ID);
if($duplicate->count() > 0) {
$increment = is_int($increment) ? $increment + 1 : 0;
$this->owner->generateURLSegment((int) $increment);
}
return $this->owner->URLSegment;
}
}

View File

@ -1,5 +0,0 @@
<?php
class AjaxTextField extends TextField {
}

View File

@ -73,7 +73,7 @@ class GridFieldAddByDBField implements GridField_ActionProvider, GridField_HTMLP
$id = $gridField->getList()->add($obj); $id = $gridField->getList()->add($obj);
if(!$id) { if(!$id) {
$gridField->setError(_t("GridFieldAddByDBField.ADDFAIL", "Unable to save " . $obj->Title . " to the database.")); $gridField->setError(_t("GridFieldAddByDBField.ADDFAIL", "Unable to save " . $obj->Title . " to the database."), "error");
} }
} else { } else {
throw new UnexpectedValueException("Invalid field (" . $dbField . ") on " . $obj->ClassName . "."); throw new UnexpectedValueException("Invalid field (" . $dbField . ") on " . $obj->ClassName . ".");

View File

@ -1,15 +0,0 @@
<?php
class GridFieldConfig_AddByDBField extends GridFieldConfig_RecordEditor {
public function __construct($itemsPerPage = null, $dataObjectField = "Title") {
parent::__construct($itemsPerPage);
// Remove uneccesary components
$this->removeComponentsByType("GridFieldAddNewButton");
// Add new components
$this->addComponent(new GridFieldAddByDBField("buttons-before-left", $dataObjectField));
}
}

View File

@ -9,7 +9,8 @@
* @package framework * @package framework
* @subpackage fields-gridfield * @subpackage fields-gridfield
*/ */
class GridFieldSiteTreeAddNewButton extends GridFieldAddNewButton { class GridFieldSiteTreeAddNewButton extends GridFieldAddNewButton
implements GridField_ActionProvider {
public function getHTMLFragments($gridField) { public function getHTMLFragments($gridField) {
$singleton = singleton($gridField->getModelClass()); $singleton = singleton($gridField->getModelClass());
@ -18,21 +19,99 @@ class GridFieldSiteTreeAddNewButton extends GridFieldAddNewButton {
return array(); return array();
} }
$parent = SiteTree::get()->byId(Controller::curr()->currentPageID());
if(!$this->buttonName) { if(!$this->buttonName) {
// provide a default button name, can be changed by calling {@link setButtonName()} on this component // provide a default button name, can be changed by calling {@link setButtonName()} on this component
$objectName = $singleton->i18n_singular_name(); $objectName = $singleton->i18n_singular_name();
$this->buttonName = _t('GridField.Add', 'Add {name}', array('name' => $objectName)); $this->buttonName = _t('GridField.Add', 'Add {name}', array('name' => $objectName));
} }
$controller = $gridField->getForm()->getController(); $state = $gridField->State->GridFieldSiteTreeAddNewButton;
$data = new ArrayData(array( $state->currentPageID = $parent->ID;
'NewLink' => $controller->LinkPageAdd("?ParentID=" . $controller->currentPageID()), $state->pageType = $parent->defaultChild();
'ButtonName' => $this->buttonName,
)); $addAction = new GridField_FormAction($gridField, 'add',
sprintf(_t('GridField.ADD', "Add %s"), $singleton->i18n_singular_name()), 'add', 'add');
$addAction->setAttribute('data-icon', 'add')->addExtraClass("no-ajax");
$allowedChildren = $parent->allowedChildren();
$children = array();
foreach($allowedChildren as $class) {
$children[$class] = singleton($class)->i18n_singular_name();
}
$pageTypes = DropdownField::create(
"PageType",
"Page Type",
$children,
$singleton->defaultChild()
);
$pageTypes->setFieldHolderTemplate("BlogDropdownField_holder")
->addExtraClass("gridfield-dropdown");
$forTemplate = new ArrayData(array());
$forTemplate->Fields = new ArrayList();
$forTemplate->Fields->push($pageTypes);
$forTemplate->Fields->push($addAction);
Requirements::css(blog_dir() . "/css/cms.css");
Requirements::javascript(blog_dir() . "/javascript/GridField.js");
return array( return array(
$this->targetFragment => $data->renderWith('GridFieldAddNewbutton'), $this->targetFragment => $forTemplate->renderWith("GridFieldSiteTreeAddNewButton")
); );
} }
/**
* Provide actions to this component.
*
* @param $gridField GridField
*
* @return array
**/
public function getActions($gridField) {
return array("add");
}
/**
* Handles the add action, but only acts as a wrapper for {@link CMSPageAddController::doAdd()}
*
* @param $gridFIeld GridFIeld
* @param $actionName string
* @param $arguments mixed
* @param $data array
**/
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if($actionName == "add") {
$tmpData = json_decode($data['BlogPost']['GridState'], true);
$tmpData = $tmpData['GridFieldSiteTreeAddNewButton'];
$data = array(
"ParentID" => $tmpData['currentPageID'],
"PageType" => $tmpData['pageType']
);
$controller = Injector::inst()->create("CMSPageAddController");
$form = $controller->AddForm();
$form->loadDataFrom($data);
$controller->doAdd($data, $form);
$response = $controller->getResponseNegotiator()->getResponse();
// Get the current record
$record = SiteTree::get()->byId($controller->currentPageID());
if($record) {
$response->redirect(Director::absoluteBaseURL() . $record->CMSEditLink(), 301);
}
return $response;
}
}
} }

16
javascript/GridField.js Executable file
View File

@ -0,0 +1,16 @@
(function($){
$.entwine('ss', function($) {
$('.ss-gridfield .field .gridfield-dropdown').entwine({
onchange: function() {
var gridField = this.getGridField();
var state = gridField.getState().GridFieldSiteTreeAddNewButton;
state.pageType = this.val();
gridField.setState("GridFieldSiteTreeAddNewButton", state);
}
});
});
}(jQuery));

View File

@ -18,8 +18,33 @@ class BlogCategory extends DataObject {
"Blog" => "Blog", "Blog" => "Blog",
); );
private static $many_many = array( private static $belongs_many_many = array(
"BlogPosts" => "BlogPost", "BlogPosts" => "BlogPost",
); );
private static $extensions = array(
"URLSegmentExtension",
);
public function getCMSFields() {
$fields = new FieldList(
TextField::create("Title", _t("BlogTag.FieldLabels.TITLE", "Title"))
);
$this->extend("updateCMSFields", $fields);
return $fields;
}
/**
* Returns a relative link to this category.
*
* @return string URL
**/
public function getLink() {
return Controller::join_links($this->Blog()->Link(), "category", $this->URLSegment);
}
} }

View File

@ -18,8 +18,30 @@ class BlogTag extends DataObject {
"Blog" => "Blog", "Blog" => "Blog",
); );
private static $many_many = array( private static $belongs_many_many = array(
"BlogPosts" => "BlogPost", "BlogPosts" => "BlogPost",
); );
private static $extensions = array(
"URLSegmentExtension",
);
public function getCMSFields() {
$fields = new FieldList(
TextField::create("Title", _t("BlogTag.FieldLabels.TITLE", "Title"))
);
$this->extend("updateCMSFields", $fields);
return $fields;
}
/**
* Returns a relative URL for the tag link.
*
* @return string URL
**/
public function getLink() {
return Controller::join_links($this->Blog()->Link(), "tag", $this->URLSegment);
}
} }

View File

@ -10,40 +10,22 @@
**/ **/
class Blog extends Page { class Blog extends Page {
private static $db = array(
"PostsPerPage" => "Int",
);
private static $has_many = array( private static $has_many = array(
"Tags" => "BlogTag", "Tags" => "BlogTag",
"Categories" => "BlogCategory" "Categories" => "BlogCategory",
); );
private static $allowed_children = array( private static $allowed_children = array(
"BlogPost" "BlogPost",
); );
private static $extensions = array(
/** "BlogFilter",
* Enable archive. );
*
* @var boolean
**/
private static $archive_enabled = true;
/**
* Enable tags
*
* @var boolean
**/
private static $tags_enabled = true;
/**
* Enable categories
*
* @var boolean
**/
private static $categories_enabled = true;
/** /**
* Whether or not to show BlogPost's in a GridField. Usually this will be * Whether or not to show BlogPost's in a GridField. Usually this will be
@ -67,27 +49,37 @@ class Blog extends Page {
$fields->addFieldToTab("Root.BlogPosts", $gridField); $fields->addFieldToTab("Root.BlogPosts", $gridField);
} }
if($this->config()->get("categories_enabled")) { // Create categories and tag config
$fields->addFieldToTab("Root." . _t("Blog.CATEGORIES", "Categories"), $config = GridFieldConfig_RecordEditor::create();
GridField::create( $config->removeComponentsByType("GridFieldAddNewButton");
$config->addComponent(new GridFieldAddByDBField("buttons-before-left"));
$categories = GridField::create(
"Categories", "Categories",
_t("Blog.FieldLabels.Categories", "Categories"), _t("Blog.FieldLabels.Categories", "Categories"),
$this->Categories(), $this->Categories(),
GridFieldConfig_AddByDBField::create() $config
)
); );
}
if($this->config()->get("tags_enabled")) { $tags = GridField::create(
$fields->addFieldToTab("Root." . _t("Blog.TAGS", "Tags"),
GridField::create(
"Tags", "Tags",
_t("Blog.FieldLabels.Tags", "Tags"), _t("Blog.FieldLabels.Tags", "Tags"),
$this->Tags(), $this->Tags(),
GridFieldConfig_AddByDBField::create() $config
)
); );
$fields->addFieldsToTab("Root.BlogOptions", array(
$categories,
$tags
));
return $fields;
} }
public function getSettingsFields() {
$fields = parent::getSettingsFields();
$fields->addFieldToTab("Root.Settings", NumericField::create("PostsPerPage", _t("Blog.FieldLabels.POSTSPERPAGE", "Posts Per Page")));
return $fields; return $fields;
} }
@ -118,7 +110,7 @@ class Blog extends Page {
* @return DataList of BlogPost objects * @return DataList of BlogPost objects
**/ **/
public function getBlogPosts() { public function getBlogPosts() {
return $this->AllChildren()->filter("ClassName", ClassInfo::subClassesFor("BlogPost")); return BlogPost::get()->filter("ParentID", $this->ID);
} }
} }
@ -142,48 +134,208 @@ class Blog_Controller extends Page_Controller {
); );
private static $url_handlers = array( private static $url_handlers = array(
'tag/$Tag' => "tag", 'tag/$Tag!' => 'tag',
'category/$Category' => "category", 'category/$Category!' => 'category',
'archive/$Year!/$Month' => 'archive',
); );
/**
* The current Blog Post DataList query.
*
* @var DataList
**/
protected $blogPosts; protected $blogPosts;
public function index() { public function index() {
$this->blogPosts = $this->AllChildren(); $this->blogPosts = $this->getBlogPosts();
return $this->render(); return $this->render();
} }
/**
* Renders an archive for a specificed date. This can be by year or year/month
*
* @return SS_HTTPResponse
**/
public function archive() { public function archive() {
$year = $this->getArchiveYear();
$month = $this->getArchiveMonth();
// If an invalid month has been passed, we can return a 404.
if($this->request->param("Month") && !$month) {
return $this->httpError(404, "Not Found");
}
if($year) {
if($month) {
$startDate = $year . '-' . $month . '-01 00:00:00';
if($month == 12) {
$endDate = ($year+1) . '-01-01 00:00:00';
} else {
$endDate = $year . '-' . ($month + 1) . '-' . '01 00:00:00';
}
} else {
$startDate = $year . '-01-01 00:00:00';
$endDate = ($year+1) . '12-31 23:59:59';
}
// Ensure that we never fetch back unpublished future posts.
if(strtotime($endDate) > time()) {
$endDate = date('Y-m-d H:i:s');
}
$query = $this->getBlogPosts()->dataQuery();
$stage = $query->getQueryParam("Versioned.stage");
if($stage) $stage = '_' . Convert::raw2sql($stage);
$query->innerJoin("BlogPost", "`SiteTree" . $stage . "`.`ID` = `BlogPost" . $stage . "`.`ID`");
$query->where("`PublishDate` >= '" . Convert::raw2sql($startDate) . "'
AND `PublishDate` < '" . Convert::raw2sql($endDate) . "'");
$this->blogPosts = $this->getBlogPosts()->setDataQuery($query);
return $this->render(); return $this->render();
} }
return $this->httpError(404, "Not Found");
}
/**
* Renders the blog posts for a given tag.
*
* @return SS_HTTPResponse
**/
public function tag() { public function tag() {
$tag = $this->getCurrentTag();
if($tag) {
$this->blogPosts = $tag->BlogPosts();
return $this->render();
}
return $this->httpError(404, "Not Found");
}
/**
* Renders the blog posts for a given category
*
* @return SS_HTTPResponse
**/
public function category() {
$category = $this->getCurrentCategory();
if($category) {
$this->blogPosts = $category->BlogPosts();
return $this->render();
}
return $this->httpError(404, "Not Found");
}
/**
* Returns a list of paginated blog posts based on the blogPost dataList
*
* @return PaginatedList
**/
public function PaginatedList() {
$posts = new PaginatedList($this->blogPosts);
// If pagination is set to '0' then no pagination will be shown.
if($this->PostsPerPage > 0) $posts->setPageLength($this->PostsPerPage);
else $posts->setPageLength($this->getBlogPosts()->count());
$start = $this->request->getVar($posts->getPaginationGetVar());
$posts->setPageStart($start);
return $posts;
}
/**
* Tag Getter for use in templates.
*
* @return BlogTag|null
**/
public function getCurrentTag() {
$tag = $this->request->param("Tag"); $tag = $this->request->param("Tag");
if($tag) { if($tag) {
$tag = $this->Tags()->filter("Title", $tag)->first(); return $this->dataRecord->Tags()
if($tag) { ->filter("URLSegment", $tag)
$this->blogPosts = $this->AllChildren()->filter("ID", $tag->BlogPosts()->getIDList()); ->first();
return $this->render();
} }
} return null;
return $this->httpError(404, "Not Found");
} }
public function category() {
/**
* Category Getter for use in templates.
*
* @return BlogCategory|null
**/
public function getCurrentCategory() {
$category = $this->request->param("Category"); $category = $this->request->param("Category");
if($category) { if($category) {
$category = $this->Categories()->filter("Title", $category)->first(); return $this->dataRecord->Categories()
if($category) { ->filter("URLSegment", $category)
$this->blogPosts = $this->AllChildren()->filter("ID", $category->BlogPosts()->getIDList()); ->first();
return $this->render();
} }
} return null;
return $this->httpError(404, "Not Found");
} }
public function PaginatedPosts() {
return new PaginatedList($this->blogPosts);
/**
* Fetches the archive year from the url
*
* @return int|null
**/
public function getArchiveYear() {
$year = $this->request->param("Year");
if(preg_match("/^[0-9]{4}$/", $year)) {
return $year;
} }
return null;
}
/**
* Fetches the archive money from the url.
*
* @return int|null
**/
public function getArchiveMonth() {
$month = $this->request->param("Month");
if(preg_match("/^[0-9]{1,2}$/", $month)) {
if($month > 0 && $month < 13)
return $month;
}
return null;
}
public function getArchiveDate() {
$year = $this->getArchiveYear();
$month = $this->getArchiveMonth();
if($year) {
if($month) {
$startDate = $year . '-' . $month . '-01 00:00:00';
} else {
$startDate = $year . '-01-01 00:00:00';
}
$date = new Date("ArchiveDate");
$date->setValue($startDate);
return $date;
}
}
} }

View File

@ -17,6 +17,19 @@ class BlogPost extends Page {
"PublishDate" => "SS_Datetime", "PublishDate" => "SS_Datetime",
); );
private static $has_one = array(
"FeaturedImage" => "Image",
);
private static $many_many = array(
"Categories" => "BlogCategory",
"Tags" => "BlogTag",
);
private static $defaults = array(
"ShowInMenus" => 0,
);
/** /**
* @var array * @var array
@ -25,12 +38,33 @@ class BlogPost extends Page {
/**
* Set the default sort to publish date
*
* @var string
**/
private static $default_sort = "PublishDate DESC";
/**
* Add blog post filter to BlogPost
*
* @var array
**/
private static $extensions = array(
"BlogPostFilter",
);
/** /**
* @var boolean * @var boolean
**/ **/
public static $can_be_root = false; public static $can_be_root = false;
/** /**
* This will display or hide the current class from the SiteTree. This * This will display or hide the current class from the SiteTree. This
* variable can be configured using YAML. * variable can be configured using YAML.
@ -40,16 +74,35 @@ class BlogPost extends Page {
private static $show_in_site_tree = false; private static $show_in_site_tree = false;
public function getCMSFields() { public function getCMSFields() {
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->insertBefore(
$publishDate = DatetimeField::create("PublishDate", _t("BlogPost.FieldLabels.PublishDate", "Publish Date")), // Add Publish date fields
$fields->insertAfter(
$publishDate = DatetimeField::create("PublishDate", _t("BlogPost.FieldLabels.PUBLISHDATE", "Publish Date")),
"Content" "Content"
); );
// Publish date field config.
$publishDate->getDateField()->setConfig("showcalendar", true); $publishDate->getDateField()->setConfig("showcalendar", true);
// Add Categories & Tags fields
$categories = $this->Parent()->Categories()->map()->toArray();
$categoriesField = ListboxField::create("Categories", _t("BlogPost.FieldLabels.CATEGORIES", "Categories"), $categories)
->setMultiple(true);
$fields->insertAfter($categoriesField, "PublishDate");
$tags = $this->Parent()->Tags()->map()->toArray();
$tagsField = ListboxField::create("Tags", _t("BlogPost.FieldLabels.TAGS", "Tags"), $tags)
->setMultiple(true);
$fields->insertAfter($tagsField, "Categories");
// Add featured image
$fields->insertBefore(
$uploadField = UploadField::create("FeaturedImage", _t("BlogPost.FieldLabels.FEATUREDIMAGE", "Featured Image")),
"Content"
);
$uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
return $fields; return $fields;
} }
@ -84,11 +137,48 @@ class BlogPost extends Page {
return true; return true;
} }
/**
* Returns the post excerpt.
*
* @param $wordCount int - number of words to display
*
* @return string
**/
public function getExcerpt($wordCount = 30) {
return $this->dbObject("Content")->LimitWordCount($wordCount);
}
/**
* Returns a monthly archive link for the current blog post.
*
* @return string URL
**/
public function getMonthlyArchiveLink() {
$date = $this->dbObject("PublishDate");
return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y"), $date->format("m"));
}
/**
* Returns a yearly archive link for the current blog post.
*
* @return string URL
**/
public function getYearlyArchiveLink() {
$date = $this->dbObject("PublishDate");
return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y"));
}
} }
/** /**
* An indivisual blog post. * Blog Post controller
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog

View File

@ -0,0 +1,21 @@
<% if $PaginatedList.MoreThanOnePage %>
<nav class="BlogPagination">
<% if $PaginatedList.NotFirstPage %>
<a class="prev" href="$PaginatedList.PrevLink">Prev</a>
<% end_if %>
<% loop $PaginatedList.Pages %>
<% if $CurrentBool %>
$PageNum
<% else %>
<% if $Link %>
<a href="$Link">$PageNum</a>
<% else %>
...
<% end_if %>
<% end_if %>
<% end_loop %>
<% if $PaginatedList.NotLastPage %>
<a class="next" href="$PaginatedList.NextLink">Next</a>
<% end_if %>
</nav>
<% end_if %>

View File

@ -0,0 +1,3 @@
<aside class="sidebar unit size1of4">
$SideBar
</aside>

View File

@ -1,18 +0,0 @@
<% include SideBar %>
<div class="content-container unit size3of4 lastUnit">
<article>
<h1>$Title</h1>
<div class="content">$Content</div>
<% if BlogPosts %>
<ul>
<% loop BlogPosts %>
<li><a href="$Link" title="$Title">$Title</a></li>
<% end_loop %>
</ul>
<% else %>
<p>Unable to find any blog posts.</p>
<% end_if %>
</article>
$Form
$PageComments
</div>

View File

@ -0,0 +1,3 @@
<div class="field<% if $extraClass %> $extraClass<% end_if %>">
$Field
</div>

View File

@ -0,0 +1,3 @@
<% loop Fields %>
$Field
<% end_loop %>

View File

@ -0,0 +1,3 @@
<% loop Fields %>
$FieldHolder
<% end_loop %>

View File

@ -0,0 +1,9 @@
<% if Archive %>
<nav class="secondary">
<ul>
<% loop Archive %>
<li><a href="$Link" title="$Title">$Title</a></li>
<% end_loop %>
</ul>
<% end_if %>
</nav>

View File

@ -0,0 +1,7 @@
<nav class="secondary">
<ul>
<% loop Categories %>
<li><a href="$Link" title="$Title">$Title</a></li>
<% end_loop %>
</ul>
</nav>

View File

@ -0,0 +1,7 @@
<nav class="secondary">
<ul>
<% loop Posts %>
<li><a href="$Link" title="$Title">$Title</a></li>
<% end_loop %>
</ul>
</nav>

View File

@ -0,0 +1,7 @@
<nav class="secondary">
<ul>
<% loop Tags %>
<li><a href="$Link" title="$Title">$Title</a></li>
<% end_loop %>
</ul>
</nav>

81
widgets/BlogArchiveWidget.php Executable file
View File

@ -0,0 +1,81 @@
<?php
class BlogArchiveWidget extends Widget {
private static $title = "Archive";
private static $cmsTitle = "Archive";
private static $description = "Displays an archive list of posts.";
private static $db = array(
"NumberToDisplay" => "Int",
"Type" => "Enum('Monthly, Yearly', 'Monthly')"
);
private static $defaults = array(
"NumberOfMonths" => 12
);
private static $has_one = array(
"Blog" => "Blog",
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$type = $this->dbObject("Type")->enumValues();
foreach($type as $k => $v) {
$type[$k] = _t("BlogArchiveWidget." . strtoupper($v), $v);
}
$fields->push(DropdownField::create("BlogID", _t("BlogArchiveWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map()));
$fields->push(DropdownField::create("Type", _t("BlogArchiveWidget.FieldLabels.TYPE", "Type"), $type));
$fields->push(NumericField::create("NumberToDisplay", _t("BlogArchiveWidget.LabelFields.NUMBERTODISPLAY", "No. to Display")));
return $fields;
}
/**
* Returns a list of months where blog posts are present.
*
* @return DataList
**/
public function getArchive() {
$query = $this->Blog()->getBlogPosts()->dataQuery();
if($this->Type == "Yearly") {
$query->groupBy("DATE_FORMAT(PublishDate, '%Y')");
} else {
$query->groupBy("DATE_FORMAT(PublishDate, '%Y-%M')");
}
$articles = $this->Blog()->getBlogPosts()->setDataQuery($query);
if($this->NumberToDisplay > 0) $articles = $articles->limit($this->NumberToDisplay);
$archive = new ArrayList();
if($articles->count() > 0) {
foreach($articles as $article) {
if($this->Type == "Yearly") {
$year = date('Y', strtotime($article->PublishDate));
$month = null;
$title = $year;
} else {
$year = date('Y', strtotime($article->PublishDate));
$month = date('m', strtotime($article->PublishDate));
$title = date('F Y', strtotime($article->PublishDate));
}
$archive->push(new ArrayData(array(
"Title" => $title,
"Link" => Controller::join_links($this->Blog()->Link("archive"), $year, $month)
)));
}
}
return $archive;
}
}
class BlogArchiveWidget_Controller extends Widget_Controller {
}

View File

@ -0,0 +1,35 @@
<?php
class BlogCategoriesWidget extends Widget {
private static $title = "Categories";
private static $cmsTitle = "Blog Categories";
private static $description = "Displays a list of blog categories.";
private static $db = array();
private static $has_one = array(
"Blog" => "Blog",
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->push(DropdownField::create("BlogID", _t("BlogCategoriesWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map()));
return $fields;
}
public function getCategories() {
$blog = $this->Blog();
if($blog) {
return $blog->Categories();
}
return array();
}
}
class BlogCategoriesWidget_Controller extends Widget_Controller {
}

View File

@ -0,0 +1,40 @@
<?php
class BlogRecentPostsWidget extends Widget {
private static $title = "Recent Posts";
private static $cmsTitle = "Recent Posts";
private static $description = "Displays a list of recent blog posts.";
private static $db = array(
"NumberOfPosts" => "Int",
);
private static $has_one = array(
"Blog" => "Blog",
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->push(DropdownField::create("BlogID", _t("BlogCategoriesWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map()));
$fields->push(NumericField::create("NumberOfPosts", _t("BlogRecentPostsWidget.FieldLabels.NUMBEROFPOSTS", "Number of Posts")));
return $fields;
}
public function getPosts() {
$blog = $this->Blog();
if($blog) {
return $blog->getBlogPosts()
->sort("PublishDate DESC")
->limit($this->NumberOfPosts);
}
return array();
}
}
class BlogRecentPostsWidget_Controller extends Widget_Controller {
}

35
widgets/BlogTagsWidget.php Executable file
View File

@ -0,0 +1,35 @@
<?php
class BlogTagsWidget extends Widget {
private static $title = "Tags";
private static $cmsTitle = "Blog Tags";
private static $description = "Displays a list of blog tags.";
private static $db = array();
private static $has_one = array(
"Blog" => "Blog",
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->push(DropdownField::create("BlogID", _t("BlogCategoriesWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map()));
return $fields;
}
public function getTags() {
$blog = $this->Blog();
if($blog) {
return $blog->Tags();
}
return array();
}
}
class BlogTagsWidget_Controller extends Widget_Controller {
}