├── .gitignore ├── README.md ├── _config.php ├── composer.json ├── css └── blog.css ├── templates └── Includes │ ├── BlogSummary.ss │ └── BlogSideBar.ss └── code ├── BlogEntryExtension.php └── BlogHolderExtension.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | silverstripe-blog-extension 2 | =========================== 3 | 4 | SilverStripe Blog Extension, adds features to Blog module -------------------------------------------------------------------------------- /_config.php: -------------------------------------------------------------------------------- 1 | =5.3.2", 5 | "silverstripe/blog": "*" 6 | } 7 | } -------------------------------------------------------------------------------- /css/blog.css: -------------------------------------------------------------------------------- 1 | .BlogError { 2 | text-align: center; 3 | } 4 | 5 | .BlogError p { 6 | color: #fff; 7 | display: inline; 8 | background-color: #f77; 9 | padding: 7px; 10 | font-weight:bold; 11 | } 12 | 13 | .edit-post { 14 | clear:both; 15 | padding-top:10px; 16 | } 17 | 18 | .blogEntry { 19 | margin: 10px 0 0; 20 | } 21 | 22 | h4.postTitle { 23 | margin-top: 10px; 24 | } 25 | 26 | .blogSummary { 27 | margin: 0 0 20px; 28 | padding: 0 0 20px; 29 | 30 | border-bottom: solid 1px #444444; 31 | } 32 | 33 | .left { 34 | float: left; 35 | margin: 0 10px 5px 0; 36 | } 37 | .right { 38 | float: right; 39 | margin: 0 0 5px 10px; 40 | } 41 | -------------------------------------------------------------------------------- /templates/Includes/BlogSummary.ss: -------------------------------------------------------------------------------- 1 |
2 |

$MenuTitle

3 |

Posted <% if Author %>by $Author.XML <% end_if %><% _t('POSTEDON', 'on') %> $Date.NiceUS

4 | 5 | 6 | <% if BlogHolder.ShowFullEntry %> 7 | $Content 8 | <% else %> 9 |

10 | <% if Image %><% end_if %> 11 | $Content.FirstParagraph(text) 12 |

13 | <% end_if %> 14 | 15 |

Read the full post

16 | 17 | <% if TagsCollection %> 18 |

19 | Tags: 20 | <% loop TagsCollection %> 21 | <% if not Last %>,<% end_if %> 22 | <% end_loop %> 23 |

24 | <% end_if %> 25 | 26 |
27 | -------------------------------------------------------------------------------- /templates/Includes/BlogSideBar.ss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /code/BlogEntryExtension.php: -------------------------------------------------------------------------------- 1 | 'Boolean' 7 | ); 8 | 9 | static $has_one = array( 10 | 'Image' => 'Image', 11 | 'Thumbnail' => 'Image' 12 | ); 13 | 14 | public function updateCMSFields(FieldList $fields) { 15 | 16 | // Main Image 17 | $ImageField = new UploadField('Image', 'Main Image'); 18 | $ImageField->getValidator()->allowedExtensions = array('jpg', 'jpeg', 'gif', 'png'); 19 | $ImageField->setConfig('allowedMaxFileNumber', 1); 20 | $ImageField->setFolderName('Uploads/BlogEntries'); 21 | $fields->addFieldToTab('Root.Images', $ImageField); 22 | 23 | // Thumbnail Image 24 | $ImageField = new UploadField('Thumbnail', 'Thumbnail Preview (square)'); 25 | $ImageField->getValidator()->allowedExtensions = array('jpg', 'jpeg', 'gif', 'png'); 26 | $ImageField->setConfig('allowedMaxFileNumber', 1); 27 | $ImageField->setFolderName('Uploads/BlogEntryThumbs'); 28 | //$fields->addFieldToTab('Root.Images', $ImageField); 29 | 30 | // featured 31 | $fields->addFieldToTab('Root.Main', new CheckboxField('Featured', 'Featured Post (display link in Featured box in sidebar)'), 'Content'); 32 | 33 | } 34 | 35 | public function getArticle() { 36 | 37 | if ($this->owner->ThumbnailID) { 38 | $extra = ''; 39 | $content = $this->owner->Content; 40 | 41 | $pos = strpos($content, '

') + 4; 42 | $content = substr($content, 0, $pos) . $extra . substr($content, $pos); 43 | } else { 44 | $content = $this->owner->Content; 45 | } 46 | 47 | return $content; 48 | } 49 | 50 | // News Archive Grouping 51 | public function getMonthCreated() { 52 | return date('F Y', strtotime($this->owner->Date)); 53 | } 54 | 55 | // resize Main image on detail 56 | public function getHeroImage() { 57 | if ($this->owner->Image()) { 58 | if ($this->owner->Image()->getWidth() > 450 || $this->owner->Image()->getHeight() > 300) { 59 | return $this->owner->Image()->SetRatioSize(450,300); 60 | } 61 | return $this->owner->Image(); 62 | } 63 | return false; 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /code/BlogHolderExtension.php: -------------------------------------------------------------------------------- 1 | filter(array('Featured' => 1))->sort('Date DESC')->limit(3); 11 | } 12 | 13 | public function getTagsList() { 14 | 15 | $allTags = array(); 16 | $max = 0; 17 | $limit = 0; 18 | $sortby = 'popularity'; 19 | $container = BlogTree::current(); 20 | 21 | $entries = BlogEntry::get(); 22 | //$entries = $this->owner->Entries(); 23 | 24 | if($entries) { 25 | foreach($entries as $entry) { 26 | $theseTags = preg_split(" *, *", mb_strtolower(trim($entry->Tags))); 27 | foreach($theseTags as $tag) { 28 | if($tag != "") { 29 | $allTags[$tag] = isset($allTags[$tag]) ? $allTags[$tag] + 1 : 1; //getting the count into key => value map 30 | $max = ($allTags[$tag] > $max) ? $allTags[$tag] : $max; 31 | } 32 | } 33 | } 34 | 35 | if($allTags) { 36 | //TODO: move some or all of the sorts to the database for more efficiency 37 | if($limit > 0) $allTags = array_slice($allTags, 0, $limit, true); 38 | 39 | if($sortby == "alphabet"){ 40 | $this->natksort($allTags); 41 | } else{ 42 | uasort($allTags, array($this, "column_sort_by_popularity")); // sort by frequency 43 | } 44 | 45 | $sizes = array(); 46 | foreach ($allTags as $tag => $count) $sizes[$count] = true; 47 | 48 | $offset = 0; 49 | 50 | $numsizes = count($sizes)-1; //Work out the number of different sizes 51 | $buckets = count(self::$popularities)-1; 52 | 53 | // If there are more frequencies than buckets, divide frequencies into buckets 54 | if ($numsizes > $buckets) { 55 | $numsizes = $buckets; 56 | } 57 | // Otherwise center use central buckets 58 | else { 59 | $offset = round(($buckets-$numsizes)/2); 60 | } 61 | /**/ 62 | 63 | foreach($allTags as $tag => $count) { 64 | $popularity = round($count / $max * $numsizes) + $offset; $popularity=min($buckets,$popularity); 65 | $class = self::$popularities[$popularity]; 66 | 67 | $allTags[$tag] = array( 68 | "Tag" => $tag, 69 | "Count" => $count, 70 | "Class" => $class, 71 | "Link" => $container->Link('tag') . '/' . urlencode($tag) 72 | ); 73 | } 74 | } 75 | 76 | $output = new ArrayList(); 77 | foreach($allTags as $tag => $fields) { 78 | $output->push(new ArrayData($fields)); 79 | } 80 | 81 | return $output->sort('Count', 'DESC')->Limit(10)->sort('Tag'); 82 | } 83 | } 84 | 85 | private function column_sort_by_popularity($a, $b){ 86 | if($a == $b) { 87 | $result = 0; 88 | } 89 | else { 90 | $result = $b - $a; 91 | } 92 | return $result; 93 | } 94 | 95 | private function natksort(&$aToBeSorted) { 96 | $aResult = array(); 97 | $aKeys = array_keys($aToBeSorted); 98 | natcasesort($aKeys); 99 | foreach ($aKeys as $sKey) { 100 | $aResult[$sKey] = $aToBeSorted[$sKey]; 101 | } 102 | $aToBeSorted = $aResult; 103 | 104 | return true; 105 | } 106 | 107 | 108 | // News Archives 109 | public function getNewsArchive() { 110 | return GroupedList::create(BlogEntry::get()->sort('Date DESC')); 111 | } 112 | 113 | 114 | 115 | } --------------------------------------------------------------------------------