Free Blog Add-On! Please review.1 user found helpful
The topic of using Concrete5 for a blog comes up time and time again. C5 is not meant to be a blog (which is why it's so awesome for non-blog sites). As Franz has mentioned in the past, blogging is a verb, not a noun (seehttp://www.concrete5.org/community/forums/customizing_c5/creating_a... andhttp://www.concrete5.org/community/forums/chat/publish-edit-like-wo... ) -- meaning that you don't need a back-end to look exactly like wordpress in order to publish timely content on the web.
While I think this misses the point that most bloggers are focused on the ACTIVITY of writing as opposed to "editing their website" -- which is where a separate wordpress installation or the paid C5 blog add-ons come in -- it does make sense when you just need a basic blog in your otherwise-non-blog site.
And putting all philosophical and architectural concerns aside, let's be honest and admit that for *some* people, not seeing a free blog option turns them off from ever trying out C5 in the first place, which is a darn shame.
SO... let's do something about this! I have put together a lightweight blog package. It's really just a collection of blocks, page types and custom templates, but that's the whole point -- if you just need a basic blog on your otherwise-non-blog site, you should do it the "C5" way -- with in-context editing on the front-end, just like any other page on your site. This will have the side benefit of demonstrating to newcomers how content on a C5 site is managed differently from Wordpress and other CMS's (i.e. on the front-end with modular content blocks, not on the back-end with monolithic WYSIWYG editors).
Please take a look at the attached package file and test it out. Let me know if you see any bugs or other problems. I will be putting this on the marketplace soon, but wanted to get community feedback first (and hopefully some help building out additional features -- see below).
Here are the features currently in the package:
* Custom template for the page_list block that grabs actual content from each page and uses that for the excerpt (as opposed to the "description" custom attribute).
* Custom RSS output for the page_list that also grabs actual content from the page.
* Simple "Post Info" block that outputs the current page's title, author and publish date.
* Copy of Tony's "Next/Previous" block for navigation between blog posts. I literally copied Tony's block (with his permission, of course) and changed all the handles so there won't be a conflict if someone already has the next/previous block installed. Thanks Tony!
* A "Blog Post" page type is installed with bloggy Page Defaults (Post Info block, 2 sample content blocks, next/previous block, and guestbook block for comments [BTW, can anyone tell me why this block is named "Guestbook" instead of "Comments"??]).
* A "Blog Index" page type is installed, and the Page List block with the custom template mentioned above is added to its Page Defaults.
That's it! To write a new post, you simply navigate to your blog index page and click "Add Page" -- just like any other type of page on your site.
This package is admittedly missing some "bloggy" features, specifically: date-based archives, categories/tags, and URL's with the year and month in them. The first two items I think can be added, but the third is not really possible (but that's okay -- this is only intended to be a "lightweight" blog -- if you need heavy duty blogability, the paid addons are available).
Here is the list of things that I would like to see this package have. If you're interested in helping out with any of these (or have any ideas of your own), let me know:
* Good icons: It needs a package icon, and also 2 icons for the Page Types. Does anyone know if it's at all possible to install new page type icons programmatically?
* Documentation: Create a sample stylesheet with CSS selectors for all of the blog index id's and classes, so styling will be a lot easier. ALSO, write instructions on how to create your own page types for the blog index and blog post pages for situations where you want to have a different page structure for your blog (this package installs new page types without template files so that the current theme's default.php gets used -- this was the best way I could think of to ensure that it will look decent in any theme "out of the box").
* Prevent output of comment count in the blog index if there's no guestbook block on the blog post page (shouldn't be too hard -- need to add something to the comment_count() function in the packages/lightweight_blog/helpers/lightweight_blog.php file).
* Replace the sample content blocks with an "Image" or "YouTube" block on the second sample blog post page that's installed by the package -- this way the user can see that they are not limited to the "Content" block on their blog posts. I don't know how to programmatically remove a block from a page and then add a new block and change its position in the page (this needs to be done from the package controller -- I know how to add blocks to the page but not remove them or rearrange them into a different order).
* Date-based archive navigation: create a custom template for the auto-nav block that outputs a hierarchical year-and-month navigation for blog posts (not unlike the paid "Date Navigation" block on the marketplace, but of course specific to this usage so less versatile and customizable). I think this can be done rather easily if the autonav block has its "Order By" option set to "Chronologically Descending" by just checking the publish date of each page in the output loop and if you hit a new month or year, output that before outputting the link to the page.
EDIT: I've removed tagging, categories, and archives from the feature list because they would be very complicated to implement, and due to the amount of effort involved it wouldn't be fair to the paid blog addons to have a free version available.
Finally, if you're interested in seeing how I built this out or want to understand the code better, check out the recipe I wrote which this package is based on:http://c5cookbook.com/recipes/make_a_blog... .
UPDATE: I've made some updates and implemented most of the features listed above -- see my comment dated "Aug 18, 2010 at 10:44 PM" for list of new features, and the updated attachment.
This looks like it just may come in really handy.
Jordan I will take a look at this more in-depth on Monday
In regards to your "Guestbook" vs "Comments"... generally speaking "Guestbooks" don't require a user to login to post an acknowledgment of their visitation.
But really, it's more of an old-skool term. "Guestbook" and "Comments Section" are synonymous.
I have a preview atLhttp://cement.performancec5.com/...
Easy to style.
Thanks for testing it out -- it does look good the way you styled it!
Regarding a couple issues you mention in the recipe...
You mentioned that subfolders could be used for categories and that such an approach would limit each post to a single category. But what about using page aliases? I've not actually used them, so I don't know if this would work or not.
Also, you mentioned that you'd have to create subfolders to implement date-based URLs , but what about "additional" URLs. A page can have as many URLs as you'd like. I have no idea how to create an "additional" (non-canonical) URL programmatically, but might that be an option?
As for the "aliases", well I honestly am not that familiar with them -- do they operate differently than the "additional URL's"? Even if so, I would hesitate to implement this as it sounds like it would pollute your sitemap and make things very confusing for the end-user (and annoying for neat-freaks like myself).
What would be ideal for this situation is if you could just use slashes in a page name, so you could have a page that was at the address "blog/2010/08/my-cool-post" without requiring a page to physically exist at the "blog/2010" and "blog/2010/08" paths. But I'm sure there are good architectural reasons for not allowing this.
Interesting idea, though -- let me know if you discover anything with aliases, as it would be good to know in general.
> this feature is that they all redirect to the
> primary path...
Not having done much blogging myself [yet], it's not clear to me why that's a problem. I guess I don't understand how date-based URLs are used in practice.
> As for the "aliases", well I honestly am not that
> familiar with them -- do they operate differently
> than the "additional URL's"?
You create them in the dashboard site map. Much like Mac aliases or Windows shortcuts, they simply point to the actual page but can reside anywhere else within the site. They have a different icon to indicate they're aliases. It doesn't seem to me they'd pollute the site map. Rather, they seem to conveniently address precisely the issue of allowing one page to have more than one parent - i.e. a blog post to be in more than one category. It seems ideally suited to the task, although I have no experience with them programmatically.
I was just tinkering a bit more with aliases, and interestingly, they might solve both problems - i.e. that of date-based URLs as well as categories. I noticed that an alias, unlike an additional URL, is NOT redirected to the original's canonical URL. So for example, if you alias the page "/projects/blogdev" to "/tech/blogdev" the URL of the alias remains "mysite.com/tech/blogdev/" in the browser address bar - i.e. no redirect. That's pretty nifty...and convenient. I can imagine a hierarchy of folders representing years, months, and days. That would seem to give you your date-based URLs without the redirect.
As for the aliases, thanks for that info -- I understand it much better now (and finally get what that "show aliases" checkbox in the autonav edit dialog is all about).
For the purposes of this lightweight solution, though, I think that's probably too much effort (more than I'm willing to put in, anyway) -- I imagine this is how the paid blog addon does it, and if they're charging then it must have required a decent amount of effort to get working smoothly.
Thanks again for the info -- nice to bounce ideas around, and learn more about the system along the way.
Ah, so it's a search engine thing. I see. Given how rapidly that technology changes, I can't see spending much time optimizing for search engines.
> if someone wants to link to that blog post by copying the URL
> in the address bar, it's not going to be the date-based one.
I guess I just don't understand the value of date-based URLs, but that's a discussion for another forum I reckon.
> I imagine the page_list block is going to list the canonical address as well
Like the auto nav block, you have the option of displaying aliases or not.
> you as the author can put in these alternate URL's, but the rest
> of the world will ignore them, so what's the point?
For blogging, I don't know, but I find them useful for brevity, clarity, and/or flexibility.
> nice to bounce ideas around, and learn more about the system
> along the way.
Yeah, no doubt.
Thanks for the awesome discussion we have going here. I'm learning a lot about C5 internals along the way!
I am running into a few problems with Page Defaults. Unbeknowenst to me (until now), the blocks on a page that come from page defaults are aliases of the block on the page defaults page -- meaning that changing content on one will affect the content on all other pages as well. At least that's the theory. What's weird is that I swear it wasn't behaving this way last week -- I seem to remember installing the package and getting 2 new sample blog posts each with different content in them. But now when I install it, the 2 sample blog posts both have the content of the 2nd page (which would seem to indicate that the blocks in question ARE aliases of the same block).
But what's even weirder is that if I edit the content of one of those pages, it now ONLY changes on that page, not on the other page (which would seem to indicate that the blocks in question are NOT aliases of the same block).
Can anyone shed some light on this situation?
Edit: As to the second point, where when you edit the block it stops acting like an alias. I think that makes sense, because when you edit a Content block, it actually creates a new block with a brand new bID in the current collection revision. I don't think that all block types behave like this... If they did, what would be the point of the column bDateModified in the Blocks table?
The other reason I wanted these content blocks in the Page Defaults, though, is because from a usability perspective, I think it would be confusing and/or annoying for people to have to add blocks to the page and then re-position them to be up in the right spot for every new blog post.
This could be solved by having different areas for the post info block at the top and the next/previous and guestbook blocks at the bottom (or just hard-code them into the page template), but the problem with this is that I don't want to include a page type template with the package because odds are it won't look right out of the box with the user's installed theme (e.g. would this have a sidebar at all? Would it be on the left or the right side of the page? What if they have a 3-column layout? And even if we assumed a standard left- or right-sidebar structure, how would we know the CSS id's and classes to use to ensure it was styled properly? etc.). Because of this, the package creates a page type that intentionally doesn't have a template file -- because this forces the system to fall back on the active theme's default.php template (which we can guarantee has the proper layout and looks right). Unfortunately, this means we can't specify any other areas or hard-code any blocks -- the only thing we can safely assume exists is a 'Main' content area (and even that is going to be problematic for some users who have non-standard themes, but it's the best we can do).
So... yeah, if I can't figure out the page defaults thing then the only solution would be to not have the content blocks in the page defaults at all. At least if I can figure out how to add the sample content blocks to the 2 sample posts and position them properly, that would provide the user with an example of how it should look -- not ideal but might be good enough for this lightweight solution.
It's a theme-independent flavor of page types that I wasn't aware of until yesterday. Maybe it could be handy for this?
This is really good to know, although I'm on the fence about using this technique for this blog package, because I wanted the ability for designers to be able to "skin" the blog post page easily by just creating the "blog_post.php" file in their theme directory. Might be worth the trade-off, though -- I'll think about that (and let me know what you think too of course).
Yeah, wrapping in view.php doesn't give designers much room for skinning. For example, it probably won't look as good without a sidebar....
I'm still trying to get my mind around the situations where it would be a good fit.
> they want this page type to look right in any site's theme
> so they coopt the view.php file to display everything outside
> of its "inner content".
I'm confused. Nowhere in the calendar package (or in any page types that I can see) is $innerContent used to render a page. To my knowledge, $innerContent is used only for single pages. With regard to page types, my understanding is that if a theme contains a PHP file whose name matches that of a page type's handle, then that file is used to render the page. Otherwise, default.php is used.
Where does view.php come in with regard to page types?
In the case of the calendar block, the template: packages/calendar/page_types/calendar_event.php does get rendered to a variable called $innerContent and wrapped in the view.php for the theme assigned to the current page. I just happened to come across this while trying to understand the render() method of concrete/libraries/view.php.
view.php is ONLY used to wrap page types in this special case where a directory named page_types exists. Freaky, huh?
So basically, it functions as a default page type (or more specifically, the "guts" of the current theme's view.php) until such a time as it's overridden.
So that prompts me to revise my notion of a theme's view.php as follows...
" Wraps single pages AS WELL AS page types for which there is no corresponding file in the current theme."
Thanks for the clarification. I never paid that much attention to the calendar package's calendar_event.php, since the first thing I did was override and customize it.
"Wraps single pages AS WELL AS page types FOUND IN A PACKAGE'S /page_types/ DIRECTORY for which there is no corresponding file in the current theme."
Which now leaves me with the question...
So you CAN override these special package page types? But if you override it (with your own template file in your theme's directory), where does all that stuff that's in the package's page_type template file go? I'm guessing it goes nowhere and you have to make sure you copy it out from there into your new overriding page type template?
What about the controller code -- I'm assuming that gets run regardless of whether the system renders the package's page_type file or your theme's overriding page_type file -- correct?
It would be great to add this to the documentation (although I still have pending doc changes from a month ago that haven't been looked at by Andy, so not sure what's going on there...)
> "Wraps single pages AS WELL AS page types FOUND IN
> A PACKAGE'S /page_types/ DIRECTORY for which there
> is no corresponding file in the current theme."
Technically, it can be in a core "page_types" directory as well, but C5 doesn't appear to be making use of that. I mean, if it's not being overridden in the current theme, it HAS to be in a "page_types" directory somewhere.
> So you CAN override these special package page types?
> But if you override it (with your own template file in your
> theme's directory), where does all that stuff that's in the
> package's page_type template file go?
When you override it, you OVERRIDE it - i.e. the file in the page_types directory is ignored if that page type is found in your theme's directory. You have to ensure that any special data used by that page type gets incorporated into your overriding template.
> if it's not being overridden in the current
> theme, it HAS to be in a "page_types"
> directory somewhere
Unless I'm misunderstanding you, I think that it doesn't have to be in a page_type directory anywhere -- if there's no page_type file, it just reverts to using the theme's default.php file (or view.php if it's a single_page).
> have to be in a page_type directory anywhere -- if there's
> no page_type file, it just reverts to using the theme's
> default.php file (or view.php if it's a single_page).
> that page type is found in your theme's directory
To clarify, when you override a package page type file, the contents do NOT get wrapped in view.php. You have full control - headers, footers, etc - just as you do with any theme template file.
> special case where a directory named page_types
> exists. Freaky, huh?
Actually, it's not too freaky, as that's how single pages work as well. You can completely override them by placing a file with the name of the single page in your theme directory. Or at least you're supposed to be able to do that according to the docs...
I've been unable to get it to work for my login page. It will show either the C5 login or the one I have in my root "single_pages" directory, but it won't show login.phjp in my theme directory. This might be a bug, as I've encountered other bugs related to path search orders in 188.8.131.52.
Although mine was about putting the overriding file in your site's top-level /single_pages/ directory, not in the theme itself, so maybe the documentation you referred to is wrong (or at least wrong in the context of system pages)? Just to be sure -- did you declare this override in config/site_theme_paths.php?
Oops! That was it! (I knew I had this working before.) Thanks, Jordan.
I had gone to the dashboard and clicked the refresh button for the single page and thought I was done. I had forgotten about making that config change. That's really awkward - just too much to remember and tinker with. I see no reason this can't be managed entirely from the dashboard.
<<I've been unable to get it to work for my login page. It will show either the C5 login or the one I have in my root "single_pages" directory, but it won't show login.phjp in my theme directory. >>
I think the reason for this is that the login theme is getting set in /concrete/config/theme_paths.php. That takes precedence over nearly every other way of setting themes. You should be able to override it by setting the theme you want in /config/site_theme_paths.php
Can you clarify which point you're responding to (or if this is just a general statement about the entire conversation) -- it's hard to tell because of the lack of indenting this far down into the thread.
My intention with this package is to help the community as a whole. I have no desire whatsoever to rob people of their livelihood, nor to do things that are out of line with the overall community.
Unfortunately, there are few guidelines about what is "right" and "wrong" in terms of free vs. paid addons. Obviously, outright stealing/copying someone else's code and claiming it as your own is wrong, but I don't see that being the case here. Rather, I think this conversation is about utilizing a certain technique that is built in to Concrete5. This technique is poorly documented, so we are trying to figure out how it works together, and using the calendar addon as a point of reference because we have all purchased it and seen the code (not unlike viewing the page source of a website to see how it works). We are not talking about how to recreate a calendar addon by reverse engineering it -- we are just trying to wrap our heads around a C5 concept.
That being said, I totally respect your opinion on this matter, and I will absolutely stay away from using this technique for the blog addon -- but I would really love to hear a more detailed explanation about your reasoning, because I want to help C5 grow in a way that's not going to hurt people.
Interesting... so I guess just calling the block controller's save() method doesn't do this, but doing it through the UI does. There must be a way to do this programatically then. I'll have to figure that out some time. (Unless someone already knows...)
* Blog Post pages are "forced" to be in a single sub-level under the main blog index page -- if the user is on a blog post page and clicks "Add Page", this new page is created directly underneath the blog index page, NOT the page that the user clicked "Add Page" from. This addresses a problem I run into with clients a lot -- one of the few poor UI aspects of C5 (in my opinion) is that there is no indication of where in the sitemap a new page is created. It's really easy to just click "Add Page" from wherever you are on the site, publish it, and then have no idea where it went because it's at a sub-sub-level, but the navigation only shows 1 level deep.
* Fixes the Page Defaults problem by programatically duplicating the default blocks on the sample pages and then deleting the original aliases (which mimics the behavior of a user editing the block from the UI).
* Truncate Characters setting is no longer ignored. If you set it to 0, then the entire first block is used for the excerpt, but if you set it to a non-zero number, it will attempt to pull only that number of characters from the first block (but of course this only applies to content or HTML blocks, because it doesn't make sense to pull 128 characters from an image or youtube block).
* @agedman fixed a bug with comment counts where they were tabulating the total for all posts because it was referencing the Page Defaults instance of the guestbook block instead of the instance of that guestbook block on a particular page. Thanks Dow!
* Comment count now doesn't show up in page list when no guestbook block is on the page.
So this is all that's left before I think this thing is ready for general consumption:
* Add an image and/or youtube block to one of the sample blog posts to demonstrate to users that they are not limited to the "Content" block.
* Sample CSS file showing id's and classes that can be "skinned"
* How-to on creating a custom page type template for blog posts
* Page Type Icons
* Package Icon
Thanks for the feedback everyone!
If there is enough interest, I could upload a package that works with older versions of Concrete5 for people who can't upgrade to 5.4.1 for some reason -- but in the meantime I think it will just cause confusion to have it both available in the marketplace AND have it built in to the new system.