Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Data Model Questions /

Different Types Of News Items


Go to End
Reply


19 Posts   5109 Views

Avatar
DanStephenson

Community Member, 115 Posts

17 January 2010 at 12:37pm

Edited: 17/01/2010 12:39pm

Hi everyone,

I am building a SilverStripe site, and using the formula in the [url=http://doc.silverstripe.org/doku.php?id=tutorial:2-extending-a-basic-site#creating_the_templates]documentation[/url] to create a news section.

What I need for my current site, is for news to be of various different types - News, Events, Press Releases, and Speeches. I'll need my News Page (ArticleHolder) to show these different items, organized by their type, as well as have separate pages for each.

I'd rather not make the user select a different page type (such as NewsArticlePage,EventArticlePage), etc to create the children of the appropriate type, and would rather have 1 child type with a dropdown to select it's type. Using this approach, how can I make my ArticleHolder sort all of the sub pages by their type (only show the last 4 of each type, and then a VIEW ALL button), AS WELL as have the user be able to visit a URL that gives them only one type of content (ie - visting articles.php?type=news would give the user only news articles)

Avatar
CodeGuerrilla

Community Member, 105 Posts

20 January 2010 at 12:36pm

Edited: 20/01/2010 12:40pm

Use $has_one relationship to ArticleCategory the code below is UNTESTED

ArticleCategory.php

class ArticleCategory extends DataObject {

}

ArticlePage.php

class ArticlePage extends Page {

static $db = array(
'Date' => 'Date',
'Author' => 'Text'
);

static $has_one = array('ArticleCategory');

}

Have a look at [url=http://doc.silverstripe.org/doku.php?id=modeladmin]ModelAdmin[/url] to maybe manage the categories you can also just manually add them to the DB if they don't change often.

ArticleHolder.php

class ArticleHolder extends Page {
static $db = array();
static $has_one = array();

static $allowed_children = array('ArticlePage');
}

class ArticleHolder_Controller extends Page_Controller {

...

public function Categories()
{
$categories = DataObject::get('ArticleCategory');
return $categories;
}

public function category()
{
$categoryid = $this->URLParams['ID'];
if(empty($categoryid)) {
$category = NULL;
} else {
$category = sprintf('ArticleCategoryID = %d', $categoryid);
}
$categories = $this->Categories();
$articles = array();
foreach($categories as $category) {
array_push($articles, DataObject::get('ArticlePage', $category, 'Date DESC', 4));
}
return new ArrayData($articles);
}
}

ArticleHolder.ss

<div id="Content" class="typography">      
$Content
<form method="post" action="news/category">
<select name="categoryID">
<option value=""></option>
<% control Categories %>
<option value="$ID">$Title</option>
<% end_control %>
</select>
</form>
<ul id="NewsList">
<% control category %>
<li class="newsDateTitle"><a href="$Link" title="Read more on &quot;{$Title}&quot;">$Title</a></li>
<li class="newsDateTitle">$Date.Nice</li>
<li class="newsSummary">$Content.FirstParagraph <a href="$Link" title="Read more on &quot;{$Title}&quot;">Read more &gt;&gt;</a></li>
<% end_control %>
</ul>
</div>

Hope this helps if it doesn't work or you need more help just ask.

Avatar
DanStephenson

Community Member, 115 Posts

20 January 2010 at 5:46pm

Edited: 20/01/2010 5:47pm

Thanks CodeGuerrilla,

That method makes a lot of sense. However, I am having a few problems with the code you posted.

I decided to hard code my categories into the database, as they will rarely change.

As such my ArticleCategory.php page looks like this (and I think this page is my problem):

class ArticleCategory extends DataObject {
   static $db = array(
      'Category' => "Enum('News,Events,Press Releases,Events,Speeches')"
   );
}

And I am adding the field to the CMS in ArticlePage.php like this:

function getCMSFields() {
      $fields = parent::getCMSFields();
$fields->addFieldToTab("Root.Content.Main", new DropdownField(
            'Category',
            'Category',
            singleton('ArticleCategory')->dbObject('Category')->enumValues()
         ), 'Content');
return $fields;

Now what happens, is when I add/edit a news article, I can see the dropdown for category, and select one, but when I save it and come back, the category is reset to "News".

Nor will any of the categories show up in the form's select box on ArticleHolder.ss template, when I view it in the browser.

The whole ArticlePage.php page:

class ArticlePage extends Page {
   static $db = array(
      'Date' => 'Date',
      'Author' => 'Text',
      'Source' => 'Text'
   );
   static $has_one = array(
      'FileUpload' => 'File',
      'ArticleCategory' => 'ArticleCategory'
   );
   
   static $defaults = array(
      'ShowInMenus' => false //do not show these pages in the main menu structure
   );
   
   static $can_be_root = false; //These pages can not be at the root level
   static $allowed_children = "none"; //articles can not have sub pages
   
   function getCMSFields() {
      $fields = parent::getCMSFields();
         $fields->removeFieldFromTab("Root.Content.Main","HeaderImage"); //No header image upload
         $fields->addFieldToTab('Root.Content.Main', new CalendarDateField('Date'), 'Content');
         $fields->addFieldToTab('Root.Content.Main', new TextField('Author'), 'Content');
         $fields->addFieldToTab('Root.Content.Main', new TextField('Source'), 'Content');
         $fields->addFieldToTab("Root.Content.Main", new DropdownField(
            'Category',
            'Category',
            singleton('ArticleCategory')->dbObject('Category')->enumValues()
         ), 'Content');
         $fields->addFieldToTab("Root.Content.Main", new FileIFrameField('FileUpload', 'Upload and Attach Document'), 'Content');
      return $fields;
   }
}

class ArticlePage_Controller extends Page_Controller {
}

Also, I am going to need to be able to link to the different "sorted" sections via a menu. Will I be able to link to a page like articles/news using the method you posted?

Avatar
CodeGuerrilla

Community Member, 105 Posts

20 January 2010 at 5:59pm

class ArticleCategory extends DataObject {
static $db = array(
'CategoryName' => "Varchar(50)"
);
}

function getCMSFields() {

$fields = parent::getCMSFields();
$categories= DataObject::get("ArticleCategory")->toDropdownMap('ID', 'CategoryName');
$fields->addFieldToTab("Root.Content.Main", new DropdownField(
'ArticleCategoryID',
'Category',
$categories
), 'Content');

Also, I am going to need to be able to link to the different "sorted" sections via a menu. Will I be able to link to a page like articles/news using the method you posted?

The basic idea is to retrieve the categories by ID (you could also chnage it to do it by name) like 'news/category/1'

The first part is the pages urlSegment second is Action third is ID (ArticleCategory)

Let me know how you go

Avatar
DanStephenson

Community Member, 115 Posts

20 January 2010 at 6:40pm

Edited: 20/01/2010 6:41pm

Thanks again for the help. I see what I was doing wrong now with the categories.

I am playing around with the code to go into ArticleHolder.ss, and I can get the selection form to go in OK:

<form method="post" action="news/category">
   <select name="categoryID">
   <% control Categories %>
   <option value="$ID">$CategoryName</option>
   <% end_control %>
</select>
   <input type="submit" />
</form>      

though when I submit it, I am taken to /news/category with no number appended.

When I add in the category control section, and refresh the page (or go directly to say news/category/1), I am sent to the SS error page and get a mess of an SQL error that the query can't be run.

Avatar
CodeGuerrilla

Community Member, 105 Posts

20 January 2010 at 6:51pm

yeah sorry my bad, the form is posting to the category action which uses $this->URLParams['ID'] try changing the code to use $_POST['categoryID'] is probably not the SS way to do it but should work, so it wont be calling the category from the url as it is posted by the form the code I posted is untested so you might have to muck with it try using Debug::show($somevar) to find out what is going on.

Avatar
Silver

Community Member, 12 Posts

20 January 2010 at 6:56pm

Hey do you guys know of any tutorials for how to add Mega drop down menus (for navigation).....and have the content controlled through SS? Thank you...

Avatar
DanStephenson

Community Member, 115 Posts

20 January 2010 at 7:12pm

I was considering using $_POST, but thought there was a better SS way to do it. $this->URLParams['ID']; works if I want to allow the user to go directly to the page, but not for form submission, which I won't need in the end anyways.

I've narrowed the problem down to the foreach statement, which I am trying to debug now. If anyone gets it before I do, post your fix here please.

Go to Top