diff --git a/_config/config.yml b/_config/config.yml index e69de29..2bf9426 100755 --- a/_config/config.yml +++ b/_config/config.yml @@ -0,0 +1,3 @@ +Member: + extensions: + - BlogMemberExtension \ No newline at end of file diff --git a/code/extensions/BlogMemberExtension.php b/code/extensions/BlogMemberExtension.php new file mode 100644 index 0000000..3ade07e --- /dev/null +++ b/code/extensions/BlogMemberExtension.php @@ -0,0 +1,76 @@ + 'Varchar', + 'BlogProfileSummary' => 'Text' + ); + + private static $has_one = array( + 'BlogProfileImage' => 'Image' + ); + + private static $belongs_many_many = array( + 'AuthoredPosts' => 'BlogPost' + ); + + public function onBeforeWrite() { + // Generate a unique URL segment for the Member. + $count = 1; + + $this->owner->URLSegment = $this->generateURLSegment(); + + while(!$this->validURLSegment()) { + $this->owner->URLSegment = preg_replace('/-[0-9]+$/', null, $this->owner->URLSegment) . '-' . $count; + $count++; + } + } + + public function updateCMSFields(FieldList $fields) { + $fields->removeByName('URLSegment'); + + return $fields; + } + + /** + * Generate a unique URL segment based on the Member's name. + * + * @return string Generated URL segment. + */ + public function generateURLSegment() { + $filter = URLSegmentFilter::create(); + $name = $this->owner->FirstName . ' ' . $this->owner->Surname; + $urlSegment = $filter->filter($name); + + // Fallback to generic profile name if path is empty (= no valid, convertable characters) + if(!$urlSegment || $urlSegment == '-' || $urlSegment == '-1') $urlSegment = "profile-$this->ID"; + + return $urlSegment; + } + + /** + * Returns TRUE if this object has a URL segment value that does not conflict with any other objects. + * + * @return bool + */ + public function validURLSegment() { + $conflict = Member::get()->filter('URLSegment', $this->owner->URLSegment); + + // If the Member we're checking against is saved, exclude them from the check. + // i.e. don't conflict against yourself. + if ($this->owner->ID) { + $conflict = $conflict->exclude('ID', $this->owner->ID); + } + + return $conflict->count() == 0; + } + +} diff --git a/code/model/Blog.php b/code/model/Blog.php index fe81ea6..a9aa25b 100644 --- a/code/model/Blog.php +++ b/code/model/Blog.php @@ -330,6 +330,16 @@ class Blog extends Page implements PermissionProvider { } + /** + * Get a link to a Member profile. + * + * @param urlSegment + * @return String + */ + public function ProfileLink($urlSegment) { + return Controller::join_links($this->Link(), 'profile', $urlSegment); + } + /** * This sets the title for our gridfield @@ -450,12 +460,14 @@ class Blog_Controller extends Page_Controller { 'tag', 'category', 'rss', + 'profile' ); private static $url_handlers = array( 'tag/$Tag!' => 'tag', 'category/$Category!' => 'category', 'archive/$Year!/$Month/$Day' => 'archive', + 'profile/$URLSegment!' => 'profile' ); @@ -473,7 +485,54 @@ class Blog_Controller extends Page_Controller { return $this->render(); } + /** + * Renders a Blog Member's profile. + * + * @return SS_HTTPResponse + **/ + public function profile() { + $profile = $this->getCurrentProfile(); + if(!$profile) { + return $this->httpError(404, 'Not Found'); + } + + $this->blogPosts = $this->getCurrentProfilePosts(); + + return $this->render(); + } + + /** + * Get the Member associated with the current URL segment. + * + * @return Member|null + **/ + public function getCurrentProfile() { + $urlSegment = $this->request->param('URLSegment'); + + if($urlSegment) { + return Member::get() + ->filter('URLSegment', $urlSegment) + ->first(); + } + + return null; + } + + /** + * Get posts related to the current Member profile + * + * @return DataList|null + **/ + public function getCurrentProfilePosts() { + $profile = $this->getCurrentProfile(); + + if($profile) { + return $profile->AuthoredPosts()->filter('ParentID', $this->ID); + } + + return null; + } /** * Renders an archive for a specificed date. This can be by year or year/month diff --git a/templates/Includes/EntryMeta.ss b/templates/Includes/EntryMeta.ss index df4dde2..0569388 100644 --- a/templates/Includes/EntryMeta.ss +++ b/templates/Includes/EntryMeta.ss @@ -1,32 +1,37 @@
+ > + $FeaturedImage.setWidth(795) + +
+ + <% if $Excerpt %> ++ $Excerpt + + <%t Blog.ReadMoreAbout "Read more about '{title}'..." title=$Title %> + +
+ <% else %> ++ <%t Blog.ReadMoreAbout "Read more about '{title}'..." title=$Title %> +
+ <% end_if %> + + <% include EntryMeta %> +- > - $FeaturedImage.setWidth(795) - -
- - <% if $Excerpt %> -- $Excerpt - - <%t Blog.ReadMoreAbout "Read more about '{title}'..." title=$Title %> - -
- <% else %> -- <%t Blog.ReadMoreAbout "Read more about '{title}'..." title=$Title %> -
- <% end_if %> - - <% include EntryMeta %> -<%t Blog.NoPosts "There are no posts" %>
diff --git a/templates/Layout/Blog_profile.ss b/templates/Layout/Blog_profile.ss new file mode 100644 index 0000000..69aaff6 --- /dev/null +++ b/templates/Layout/Blog_profile.ss @@ -0,0 +1,23 @@ +<% require themedCSS('blog', 'blog') %> + +