Addd GridField component for managing BlogPosts and added composer file

This commit is contained in:
micmania1 2013-08-10 23:34:46 +01:00
parent b077e587df
commit 049edf48fb
144 changed files with 422 additions and 127 deletions

23
LICENSE.txt Executable file
View File

@ -0,0 +1,23 @@
Copyright (c) 2013, Michael Strong
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,7 +0,0 @@
---
Only:
moduleexists: 'widgets'
---
BlogPost:
defaults:
'InheritSideBar': true

21
composer.json Executable file
View File

@ -0,0 +1,21 @@
{
"name": "micmania1/silverstripe-blog",
"description": "A fresh take on blogging in Silverstripe set out to tackle the issue of a cluttered Site Tree.",
"type": "silverstripe-module",
"require": {
"silverstripe/framework": "3.1.*",
"silverstripe/cms": "3.1.*"
},
"license": "BSD-2-Clause",
"authors": [
{
"name": "Michael Strong",
"email": "micmania@hotmail.co.uk"
}
],
"suggest": {
"silverstripe/widgets": "Some widgets come with the blog which are compatible with the widgets module.",
"silverstripe/comments": "This module adds comments to your blog."
},
"minimum-stability": "dev"
}

24
config.rb Executable file
View File

@ -0,0 +1,24 @@
# Require any additional compass plugins here.
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "scss"
images_dir = "images"
javascripts_dir = "javascript"
# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
# To enable relative paths to assets via compass helper functions. Uncomment:
relative_assets = true
# To disable debugging comments that display the original location of your selectors. Uncomment:
line_comments = true
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass scss scss && rm -rf sass && mv scss sass

View File

@ -1,9 +1,35 @@
.cms .ss-gridfield .gridfield-dropdown { /**
margin: 3px 8px 0 0; * CMS Styles
border-bottom: none; **/
/**
* Include Compass framework */
/*
* Sprite maps & Icons */
/* line 42, blog-icon/*.png */
.blog-icon-sprite, .blog-icon .blog-icon-timer {
background: url('../images/blog-icon-s1d712fffa2.png') no-repeat;
} }
/* line 60, ../../../../lib/gems/1.8/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss */
.blog-icon .blog-icon-timer {
background-position: 0 0;
}
/* line 21, ../scss/cms.scss */
.cms .ss-gridfield .gridfield-dropdown {
margin: 3px 8px 0 0;
border-bottom: none;
}
/* line 26, ../scss/cms.scss */
.cms .ss-gridfield .gridfield-dropdown .chzn-container, .cms .ss-gridfield .gridfield-dropdown .chzn-container,
.cms .ss-gridfield .gridfield-dropdown .dropdown { .cms .ss-gridfield .gridfield-dropdown .dropdown {
min-width: 195px; min-width: 195px;
}
/* line 35, ../scss/cms.scss */
.cms table.ss-gridfield-table tr td .blog-icon {
width: 16px;
height: 16px;
display: block;
float: left;
margin-right: 6px;
} }

View File

@ -7,11 +7,13 @@ class BlogPostFilter extends DataExtension {
**/ **/
public function augmentSQL(SQLQuery &$query) { public function augmentSQL(SQLQuery &$query) {
$stage = Versioned::current_stage(); if(!Permission::check("VIEW_DRAFT_CONTENT")) {
if($stage == "Stage") $stage = ""; $stage = Versioned::current_stage();
else $stage = "_" . Convert::raw2sql($stage); if($stage == "Stage") $stage = "";
else $stage = "_" . Convert::raw2sql($stage);
$query->addWhere("PublishDate < NOW()"); $query->addWhere("PublishDate < NOW()");
}
} }

View File

@ -73,7 +73,15 @@ 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."), "error"); $gridField->setError(_t(
"GridFieldAddByDBField.AddFail",
"Unable to save {class} to the database.",
"Unable to add the DataObject.",
array(
"class" => $obj->class
)),
"error"
);
} }
} else { } else {
throw new UnexpectedValueException("Invalid field (" . $dbField . ") on " . $obj->ClassName . "."); throw new UnexpectedValueException("Invalid field (" . $dbField . ") on " . $obj->ClassName . ".");
@ -99,8 +107,12 @@ class GridFieldAddByDBField implements GridField_ActionProvider, GridField_HTMLP
->setAttribute("placeholder", $obj->fieldLabel($dbField)) ->setAttribute("placeholder", $obj->fieldLabel($dbField))
->addExtraClass("no-change-track"); ->addExtraClass("no-change-track");
$addAction = new GridField_FormAction($gridField, 'add', $addAction = new GridField_FormAction($gridField,
sprintf(_t('GridField.ADD', "Add %s"), $obj->i18n_singular_name()), 'add', 'add'); 'add',
_t('GridFieldAddByDBField.Add', "Add {name}", "Add button text", array("name" => $obj->i18n_singular_name())),
'add',
'add'
);
$addAction->setAttribute('data-icon', 'add'); $addAction->setAttribute('data-icon', 'add');
// Start thinking about rending this back to the GF // Start thinking about rending this back to the GF

View File

@ -9,7 +9,7 @@
* @package framework * @package framework
* @subpackage fields-gridfield * @subpackage fields-gridfield
*/ */
class GridFieldSiteTreeAddNewButton extends GridFieldAddNewButton class GridFieldBlogPostAddNewButton extends GridFieldAddNewButton
implements GridField_ActionProvider { implements GridField_ActionProvider {
public function getHTMLFragments($gridField) { public function getHTMLFragments($gridField) {
@ -24,15 +24,19 @@ class GridFieldSiteTreeAddNewButton extends GridFieldAddNewButton
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('GridFieldSiteTreeAddNewButton.Add', 'Add {name}', "Add button text", array('name' => $singleton->i18n_singular_name()));
} }
$state = $gridField->State->GridFieldSiteTreeAddNewButton; $state = $gridField->State->GridFieldSiteTreeAddNewButton;
$state->currentPageID = $parent->ID; $state->currentPageID = $parent->ID;
$state->pageType = $parent->defaultChild(); $state->pageType = $parent->defaultChild();
$addAction = new GridField_FormAction($gridField, 'add', $addAction = new GridField_FormAction($gridField,
sprintf(_t('GridField.ADD', "Add %s"), $singleton->i18n_singular_name()), 'add', 'add'); 'add',
$this->buttonName,
'add',
'add'
);
$addAction->setAttribute('data-icon', 'add')->addExtraClass("no-ajax"); $addAction->setAttribute('data-icon', 'add')->addExtraClass("no-ajax");
$allowedChildren = $parent->allowedChildren(); $allowedChildren = $parent->allowedChildren();

View File

@ -0,0 +1,72 @@
<?php
class GridFieldBlogPostState implements GridField_ColumnProvider {
public function augmentColumns($gridField, &$columns) {
// Ensure Actions always appears as the last column.
$key = array_search("Actions", $columns);
if($key !== FALSE) unset($columns[$key]);
$columns = array_merge($columns, array(
"State",
"Actions",
));
}
public function getColumnsHandled($gridField) {
return array("State");
}
public function getColumnContent($gridField, $record, $columnName) {
if($columnName == "State") {
if($record->hasMethod("isPublished")) {
$published = $record->isPublished();
if(!$published) {
return _t("GridFieldBlogPostState.Draft", '<i class="btn-icon blog-icon btn-icon-pencil"></i> Saved as Draft');
} else if (strtotime($record->PublishDate) > time()) {
return _t(
"GridFieldBlogPostState.Timer",
'<i class="blog-icon blog-icon-timer"></i> Publish at {date}',
"State for when a post is published.", array(
"date" => $record->dbObject("PublishDate")->Nice()
)
);
} else {
return _t(
"GridFieldBlogPostState.Published",
'<i class="btn-icon blog-icon btn-icon-accept"></i> Published on {date}',
"State for when a post is published.",
array(
"date" => $record->dbObject("PublishDate")->Nice()
)
);
}
}
}
}
public function getColumnAttributes($gridField, $record, $columnName) {
if($columnName == "State") {
if($record->hasMethod("isPublished")) {
$published = $record->isPublished();
if(!$published) {
$class = "blog-icon draft";
} else if (strtotime($record->PublishDate) > time()) {
$class = "blog-icon timer";
} else {
$class = "blog-icon published";
}
return array("class" => $class);
}
}
return array();
}
public function getColumnMetaData($gridField, $columnName) {
switch($columnName) {
case 'State':
return array("title" => _t("GridFieldBlogPostState.StateTitle", "State", "Column title for state"));
}
}
}

View File

@ -8,12 +8,12 @@
* *
* @author Michael String <micmania@hotmail.co.uk> * @author Michael String <micmania@hotmail.co.uk>
**/ **/
class GridFieldConfig_SiteTree extends GridFieldConfig { class GridFieldConfig_BlogPost extends GridFieldConfig {
public function __construct($itemsPerPage = null) { public function __construct($itemsPerPage = null) {
parent::__construct($itemsPerPage); parent::__construct($itemsPerPage);
$this->addComponent(new GridFieldButtonRow('before')); $this->addComponent(new GridFieldButtonRow('before'));
$this->addComponent(new GridFieldSiteTreeAddNewButton('buttons-before-left')); $this->addComponent(new GridFieldBlogPostAddNewButton('buttons-before-left'));
$this->addComponent(new GridFieldToolbarHeader()); $this->addComponent(new GridFieldToolbarHeader());
$this->addComponent($sort = new GridFieldSortableHeader()); $this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader()); $this->addComponent($filter = new GridFieldFilterHeader());
@ -21,7 +21,8 @@ class GridFieldConfig_SiteTree extends GridFieldConfig {
$this->addComponent(new GridFieldSiteTreeEditButton()); $this->addComponent(new GridFieldSiteTreeEditButton());
$this->addComponent(new GridFieldPageCount('toolbar-header-right')); $this->addComponent(new GridFieldPageCount('toolbar-header-right'));
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage)); $this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$this->addComponent(new GridFieldBlogPostState());
$pagination->setThrowExceptionOnBadDataType(false); $pagination->setThrowExceptionOnBadDataType(true);
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

BIN
images/blog-icon/timer.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

0
lang/_manifest_exclude Normal file
View File

37
lang/en.yml Executable file
View File

@ -0,0 +1,37 @@
en:
GridFieldAddByDBField:
AddFail: 'Unable to save {class} to the database.'
Add: 'Add {name}'
GridFieldSiteTreeAddNewButton:
Add: 'Add {name}'
GridFieldBlogPostState:
StateTitle: 'State'
Draft: '<i class="btn-icon blog-icon btn-icon-pencil"></i> Saved as Draft'
Published: '<i class="btn-icon blog-icon btn-icon-accept"></i> Published on {date}'
Timer: '<i class="blog-icon blog-icon-timer"></i> Publish at {date}'
BlogPost:
PublishDate: 'Publish Date'
Categories: 'Categories'
Tags: 'Tags'
FeaturedImage: 'Featured Image'
Blog:
BlogPosts: 'Blog Posts'
Categories: 'Categories'
Tags: 'Tags'
PostsPerPage: 'Posts Per Page'
BlogTag:
Title: 'Title'
BlogCategory:
Title: 'Title'
BlogRecentPostsWidget:
Blog: 'Blog'
NumberOfPosts: 'Number of Posts'
BlogCategoriesWidget:
Blog: 'Blog'
BlogArchiveWidget:
Blog: 'Blog'
Monthly: 'Monthly'
Yearly: 'Yearly'
NumberToDisplay: 'Number to Display'
BlogTagsWidget:
Blog: 'Blog'

View File

@ -27,24 +27,19 @@ class Blog extends Page {
"BlogFilter", "BlogFilter",
); );
/** private static $defaults = array(
* Whether or not to show BlogPost's in a GridField. Usually this will be "ProvideComments" => false,
* the case when they're hidden from the SiteTree. );
*
* @var boolean
**/
private static $show_posts_in_gridfield = true;
public function getCMSFields() { public function getCMSFields() {
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
if($this->config()->get("show_posts_in_gridfield")) { if(!Config::inst()->get("BlogPost", "show_in_sitetree")) {
$gridField = new GridField( $gridField = new GridField(
"BlogPost", "BlogPost",
_t("Blog.FieldLabels.BlogPosts", "Blog Posts"), _t("Blog.BlogPosts", "Blog Posts"),
$this->AllChildrenIncludingDeleted(), $this->getBlogPosts(),
GridFieldConfig_SiteTree::create() GridFieldConfig_BlogPost::create()
); );
$fields->addFieldToTab("Root.BlogPosts", $gridField); $fields->addFieldToTab("Root.BlogPosts", $gridField);
} }
@ -56,14 +51,14 @@ class Blog extends Page {
$categories = GridField::create( $categories = GridField::create(
"Categories", "Categories",
_t("Blog.FieldLabels.Categories", "Categories"), _t("Blog.Categories", "Categories"),
$this->Categories(), $this->Categories(),
$config $config
); );
$tags = GridField::create( $tags = GridField::create(
"Tags", "Tags",
_t("Blog.FieldLabels.Tags", "Tags"), _t("Blog.Tags", "Tags"),
$this->Tags(), $this->Tags(),
$config $config
); );
@ -79,7 +74,7 @@ class Blog extends Page {
public function getSettingsFields() { public function getSettingsFields() {
$fields = parent::getSettingsFields(); $fields = parent::getSettingsFields();
$fields->addFieldToTab("Root.Settings", NumericField::create("PostsPerPage", _t("Blog.FieldLabels.POSTSPERPAGE", "Posts Per Page"))); $fields->addFieldToTab("Root.Settings", NumericField::create("PostsPerPage", _t("Blog.PostsPerPage", "Posts Per Page")));
return $fields; return $fields;
} }
@ -94,8 +89,8 @@ class Blog extends Page {
public function getExcludedSiteTreeClassNames() { public function getExcludedSiteTreeClassNames() {
$classes = array(); $classes = array();
$tmpClasses = ClassInfo::subClassesFor("BlogPost"); $tmpClasses = ClassInfo::subClassesFor("BlogPost");
foreach($tmpClasses as $class) { if(!Config::inst()->get("BlogPost", "show_in_sitetree")) {
if(!Config::inst()->get($class, "show_in_site_tree")) { foreach($tmpClasses as $class) {
$classes[$class] = $class; $classes[$class] = $class;
} }
} }
@ -131,12 +126,13 @@ class Blog_Controller extends Page_Controller {
'archive', 'archive',
'tag', 'tag',
'category', 'category',
'rss',
); );
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', 'archive/$Year!/$Month/$Day' => 'archive',
); );
@ -164,38 +160,32 @@ class Blog_Controller extends Page_Controller {
public function archive() { public function archive() {
$year = $this->getArchiveYear(); $year = $this->getArchiveYear();
$month = $this->getArchiveMonth(); $month = $this->getArchiveMonth();
$day = $this->getArchiveDay();
// If an invalid month has been passed, we can return a 404. // If an invalid month has been passed, we can return a 404.
if($this->request->param("Month") && !$month) { if($this->request->param("Month") && !$month) {
return $this->httpError(404, "Not Found"); return $this->httpError(404, "Not Found");
// Check for valid day
if($this->request->param("Day") && !$day) {
return $this->httpError(404, "Not Found");
}
} }
if($year) { 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(); $query = $this->getBlogPosts()->dataQuery();
$stage = $query->getQueryParam("Versioned.stage"); $stage = $query->getQueryParam("Versioned.stage");
if($stage) $stage = '_' . Convert::raw2sql($stage); if($stage) $stage = '_' . Convert::raw2sql($stage);
$query->innerJoin("BlogPost", "`SiteTree" . $stage . "`.`ID` = `BlogPost" . $stage . "`.`ID`"); $query->innerJoin("BlogPost", "`SiteTree" . $stage . "`.`ID` = `BlogPost" . $stage . "`.`ID`");
$query->where("`PublishDate` >= '" . Convert::raw2sql($startDate) . "' $query->where("YEAR(PublishDate) = '" . Convert::raw2sql($year) . "'");
AND `PublishDate` < '" . Convert::raw2sql($endDate) . "'"); if($month) {
$query->where("MONTH(PublishDate) = '" . Convert::raw2sql($month) . "'");
if($day) {
$query->where("DAY(PublishDate) = '" . Convert::raw2sql($day) . "'");
}
}
$this->blogPosts = $this->getBlogPosts()->setDataQuery($query); $this->blogPosts = $this->getBlogPosts()->setDataQuery($query);
return $this->render(); return $this->render();
@ -237,6 +227,18 @@ class Blog_Controller extends Page_Controller {
/**
* Displays an RSS feed of blog posts
*
* @return string HTML
**/
public function rss() {
$rss = new RSSFeed($this->getBlogPosts(), $this->Link(), $this->MetaDescription, $this->MetaTitle);
return $rss->outputToBrowser();
}
/** /**
* Returns a list of paginated blog posts based on the blogPost dataList * Returns a list of paginated blog posts based on the blogPost dataList
* *
@ -299,7 +301,7 @@ class Blog_Controller extends Page_Controller {
public function getArchiveYear() { public function getArchiveYear() {
$year = $this->request->param("Year"); $year = $this->request->param("Year");
if(preg_match("/^[0-9]{4}$/", $year)) { if(preg_match("/^[0-9]{4}$/", $year)) {
return $year; return (int) $year;
} }
return null; return null;
} }
@ -314,28 +316,69 @@ class Blog_Controller extends Page_Controller {
public function getArchiveMonth() { public function getArchiveMonth() {
$month = $this->request->param("Month"); $month = $this->request->param("Month");
if(preg_match("/^[0-9]{1,2}$/", $month)) { if(preg_match("/^[0-9]{1,2}$/", $month)) {
if($month > 0 && $month < 13) if($month > 0 && $month < 13) {
return $month; // Check that we have a valid date.
if(checkdate($month, 01, $this->getArchiveYear())) {
return (int) $month;
}
}
} }
return null; return null;
} }
/**
* Fetches the archive day from the url
*
* @return int|null
**/
public function getArchiveDay() {
$day = $this->request->param("Day");
if(preg_match("/^[0-9]{1,2}$/", $day)) {
// Check that we have a valid date
if(checkdate($this->getArchiveMonth(), $day, $this->getArchiveYear())) {
return (int) $day;
}
}
return null;
}
/**
* Returns the current archive date.
*
* @return Date
**/
public function getArchiveDate() { public function getArchiveDate() {
$year = $this->getArchiveYear(); $year = $this->getArchiveYear();
$month = $this->getArchiveMonth(); $month = $this->getArchiveMonth();
$day = $this->getArchiveDay();
if($year) { if($year) {
if($month) { if($month) {
$startDate = $year . '-' . $month . '-01 00:00:00'; $date = $year . '-' . $month . '-01';
if($day) {
$date = $year . '-' . $month . '-' . $day;
}
} else { } else {
$startDate = $year . '-01-01 00:00:00'; $date = $year . '-01-01';
} }
$date = new Date("ArchiveDate"); return DBField::create_field("Date", $date);
$date->setValue($startDate);
return $date;
} }
} }
/**
* Returns a link to the RSS feed.
*
* @return string URL
**/
public function getRSSLink() {
return $this->Link("rss");
}
} }

View File

@ -30,7 +30,7 @@ class BlogCategory extends DataObject {
public function getCMSFields() { public function getCMSFields() {
$fields = new FieldList( $fields = new FieldList(
TextField::create("Title", _t("BlogTag.FieldLabels.TITLE", "Title")) TextField::create("Title", _t("BlogCategory.Title", "Title"))
); );
$this->extend("updateCMSFields", $fields); $this->extend("updateCMSFields", $fields);
return $fields; return $fields;

View File

@ -27,51 +27,36 @@ class BlogPost extends Page {
); );
private static $defaults = array( private static $defaults = array(
"ShowInMenus" => 0, "ShowInMenus" => false,
"InheritSideBar" => true, // Support for widgets
"ProvideComments" => true, // Support for comments
); );
/**
* @var array
**/
private static $allowed_children = array(); private static $allowed_children = array();
/**
* 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( private static $extensions = array(
"BlogPostFilter", "BlogPostFilter",
); );
private static $searchable_fields = array(
"Title"
);
private static $summary_fields = array(
"Title",
);
private static $default_sort = "PublishDate DESC";
/**
* @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.
* *
* @var boolean * @var boolean
**/ **/
private static $show_in_site_tree = false; private static $show_in_sitetree = false;
@ -80,25 +65,25 @@ class BlogPost extends Page {
// Add Publish date fields // Add Publish date fields
$fields->insertAfter( $fields->insertAfter(
$publishDate = DatetimeField::create("PublishDate", _t("BlogPost.FieldLabels.PUBLISHDATE", "Publish Date")), $publishDate = DatetimeField::create("PublishDate", _t("BlogPost.PublishDate", "Publish Date")),
"Content" "Content"
); );
$publishDate->getDateField()->setConfig("showcalendar", true); $publishDate->getDateField()->setConfig("showcalendar", true);
// Add Categories & Tags fields // Add Categories & Tags fields
$categories = $this->Parent()->Categories()->map()->toArray(); $categories = $this->Parent()->Categories()->map()->toArray();
$categoriesField = ListboxField::create("Categories", _t("BlogPost.FieldLabels.CATEGORIES", "Categories"), $categories) $categoriesField = ListboxField::create("Categories", _t("BlogPost.Categories", "Categories"), $categories)
->setMultiple(true); ->setMultiple(true);
$fields->insertAfter($categoriesField, "PublishDate"); $fields->insertAfter($categoriesField, "PublishDate");
$tags = $this->Parent()->Tags()->map()->toArray(); $tags = $this->Parent()->Tags()->map()->toArray();
$tagsField = ListboxField::create("Tags", _t("BlogPost.FieldLabels.TAGS", "Tags"), $tags) $tagsField = ListboxField::create("Tags", _t("BlogPost.Tags", "Tags"), $tags)
->setMultiple(true); ->setMultiple(true);
$fields->insertAfter($tagsField, "Categories"); $fields->insertAfter($tagsField, "Categories");
// Add featured image // Add featured image
$fields->insertBefore( $fields->insertBefore(
$uploadField = UploadField::create("FeaturedImage", _t("BlogPost.FieldLabels.FEATUREDIMAGE", "Featured Image")), $uploadField = UploadField::create("FeaturedImage", _t("BlogPost.FeaturedImage", "Featured Image")),
"Content" "Content"
); );
$uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif')); $uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
@ -155,11 +140,20 @@ class BlogPost extends Page {
/** /**
* Returns a monthly archive link for the current blog post. * Returns a monthly archive link for the current blog post.
* *
* @param $type string day|month|year
*
* @return string URL * @return string URL
**/ **/
public function getMonthlyArchiveLink() { public function getMonthlyArchiveLink($type = "day") {
$date = $this->dbObject("PublishDate"); $date = $this->dbObject("PublishDate");
return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y"), $date->format("m")); $year = $date->format("Y");
if($type != "year") {
if($type == "day") {
return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y"), $date->format("m"), $date->format("d"));
}
return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y"), $date->format("m"));
}
return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y"));
} }

View File

@ -28,7 +28,7 @@ class BlogTag extends DataObject {
public function getCMSFields() { public function getCMSFields() {
$fields = new FieldList( $fields = new FieldList(
TextField::create("Title", _t("BlogTag.FieldLabels.TITLE", "Title")) TextField::create("Title", _t("BlogTag.Title", "Title"))
); );
$this->extend("updateCMSFields", $fields); $this->extend("updateCMSFields", $fields);
return $fields; return $fields;

45
scss/cms.scss Executable file
View File

@ -0,0 +1,45 @@
/**
* CMS Styles
**/
/**
* Include Compass framework */
@import "compass";
/*
* Sprite maps & Icons */
@import "compass/utilities/sprites/base";
@import "blog-icon/*.png";
.blog-icon {
@include all-blog-icon-sprites;
}
.cms {
.ss-gridfield {
.gridfield-dropdown {
margin: 3px 8px 0 0;
border-bottom: none;
.chzn-container,
.dropdown {
min-width: 195px;
}
}
}
table.ss-gridfield-table {
tr {
td {
.blog-icon {
width: 16px;
height: 16px;
display: block;
float: left;
margin-right: 6px;
}
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -26,12 +26,12 @@ class BlogArchiveWidget extends Widget {
$type = $this->dbObject("Type")->enumValues(); $type = $this->dbObject("Type")->enumValues();
foreach($type as $k => $v) { foreach($type as $k => $v) {
$type[$k] = _t("BlogArchiveWidget." . strtoupper($v), $v); $type[$k] = _t("BlogArchiveWidget." . ucfirst(strtolower($v)), $v);
} }
$fields->push(DropdownField::create("BlogID", _t("BlogArchiveWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map())); $fields->push(DropdownField::create("BlogID", _t("BlogArchiveWidget.Blog", "Blog"), Blog::get()->map()));
$fields->push(DropdownField::create("Type", _t("BlogArchiveWidget.FieldLabels.TYPE", "Type"), $type)); $fields->push(DropdownField::create("Type", _t("BlogArchiveWidget.Type", "Type"), $type));
$fields->push(NumericField::create("NumberToDisplay", _t("BlogArchiveWidget.LabelFields.NUMBERTODISPLAY", "No. to Display"))); $fields->push(NumericField::create("NumberToDisplay", _t("BlogArchiveWidget.NumberToDisplay", "No. to Display")));
return $fields; return $fields;
} }

View File

@ -16,7 +16,7 @@ class BlogCategoriesWidget extends Widget {
public function getCMSFields() { public function getCMSFields() {
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->push(DropdownField::create("BlogID", _t("BlogCategoriesWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map())); $fields->push(DropdownField::create("BlogID", _t("BlogCategoriesWidget.Blog", "Blog"), Blog::get()->map()));
return $fields; return $fields;
} }

View File

@ -18,8 +18,8 @@ class BlogRecentPostsWidget extends Widget {
public function getCMSFields() { public function getCMSFields() {
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->push(DropdownField::create("BlogID", _t("BlogCategoriesWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map())); $fields->push(DropdownField::create("BlogID", _t("BlogRecentPostsWidget.Blog", "Blog"), Blog::get()->map()));
$fields->push(NumericField::create("NumberOfPosts", _t("BlogRecentPostsWidget.FieldLabels.NUMBEROFPOSTS", "Number of Posts"))); $fields->push(NumericField::create("NumberOfPosts", _t("BlogRecentPostsWidget.NumberOfPosts", "Number of Posts")));
return $fields; return $fields;
} }

View File

@ -16,7 +16,7 @@ class BlogTagsWidget extends Widget {
public function getCMSFields() { public function getCMSFields() {
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->push(DropdownField::create("BlogID", _t("BlogCategoriesWidget.FieldLabels.BLOG", "Blog"), Blog::get()->map())); $fields->push(DropdownField::create("BlogID", _t("BlogTagsWidget.Blog", "Blog"), Blog::get()->map()));
return $fields; return $fields;
} }