Jump to content

Module: Blog


Recommended Posts

The Module Blog for ProcessWire replicates and extends the popular Blog Profile.

Blog is now in version 2.

Please read the README in the Github link below in its entirety before using this module 

As of 20 December 2017 ProcessWire versions earlier than 3.x are not supported

Blog Documentation is here (Work in Progress!)

See this post for new features in version 2 or the readme in GitHub.

To upgrade from version 1, see these instructions.


Most of the text below refers to Blog version 1 (left here for posterity)


Blog version 1 consists of two modules:

ProcessBlog: Manage Blog in the backend/Admin.

MarkupBlog: Display Blog in the frontend.

Being a module, Blog can be installed in both fresh and existing sites. Note, however, that presently, ProcessBlog is not compatible with existing installs of the Blog Profile. This is because of various structural and naming differences in respect of Fields, Templates, Template Files and Pages. If there is demand for such compatibility, I will code a separate version for managing Blog Profile installs.

In order to use the 'Recent Tweets Widget', you will need to separately install and setup the module 'MarkupTwitterFeed'.

Please read the README in the Github link below in its entirety before using this module (especially the bit about the Pages, etc. created by the module). 

I'll appreciate Beta testers, thanks! Stable release works fine.


Modules Directory: http://modules.processwire.com/modules/process-blog/


You can also install from right within your ProcessWire install.

Screenshots (Blog version 1)


Video Demos




Ryan Cramer

The Alpha Testers and 'Critics'  :-)



  • Like 46
  • Thanks 1
Link to comment
Share on other sites

A very wonderful and remarkable piece of work.  Thank you for producing this module.  

I believe and certainly hope that this module will further open the door for acceptance of ProcessWire in a lot of places.

Kongondo, you have talent. 

  • Like 8
Link to comment
Share on other sites

I just installed this module on an existing test site. So far all I can say is "wow!!!"

I did try Ryan's Blog Profile, which is also amazing. The profile seems to have everything. 

This Blog module seems to offer the perfect solution to "I need a blog/news/article system for an existing PW site".

I will need to dig into the folders, especially the CSS, to see how difficult it will be to make the Bog module structure fit in with the navigation and design of the previously existing test site...

Hats off to you Kongondo...

  • Like 2
Link to comment
Share on other sites

Installed, wow! Amazing work.

Already a first beta-testing feedback: I have templates with the word "widget" in template name. They show up in the dashboard > settings tab though they have nothing to do with the blog. And if you publish a post from the dashboard > posts tab, the posts list doesn't update (the post remains as unpublished until you refresh your browser). That could be confusing to the unexperienced.

  • Like 1
Link to comment
Share on other sites

kongondo - really fantastic - you have put a huge amount of thought and work into this.

I just tested an import from WP using the latest version of Nico's MigratorWordpress. I just edited the config settings in his module to match your template and field names and bingo, a perfect import!

  • Like 5
Link to comment
Share on other sites

Installed, wow! Amazing work.

Already a first beta-testing feedback: I have templates with the word "widget" in template name. They show up in the dashboard > settings tab though they have nothing to do with the blog. And if you publish a post from the dashboard > posts tab, the posts list doesn't update (the post remains as unpublished until you refresh your browser). That could be confusing to the unexperienced.

Thanks for testing totoff.

I believe you are referring to these template files: blog-recent-comments; blog-recent-posts; and blog-recent-tweets. Yes, currently, the template files are not being used. I have been mulling whether to leave them as is for those who wish to directly render the contents of those template files. I'll think a bit more about this but it is likely I will remove the template files. Incidentally, the first 2 templates are quite similar; will probably merge them into one. 

Regarding your second issue, I haven't experienced that (see also video demo). Publishing a post using the 'posts' view, whether as unpublished or published, forces a reload of the page since a button is clicked. The 'posts' table below then shows the newly created post at the very top (selector sorting is by date descending). I think what you probably mean is that when you edit a post, the new post status is not reflected in the posts table. That is correct; this is because the editing happens in a modal (actually an iframe) that is not really aware of the 'page below it'. I will see if I can use jQuery to force a reload of the 'page below' [hope this makes sense! ;-)]

Link to comment
Share on other sites

Hi all,

Thanks for testing and comments.

Template Files

One thing I should have clarified. The included demo example template files are just that; a demo. They are not part of the 'blog' module. They are not meant to showcase any templating approach. They are intentionally verbose (e.g. similar markup repeated across all of them as opposed to, for example, using head.inc, footer.inc or some other approach e.g., main.php, etc.). The idea is that the user decides how to structure their blog, what CSS framework to use (or not to use), JS, etc. On the contrary, the template files are meant to showcase MarkupBlog. What you can do with its methods/functions. Yes, MarkupBlog generates some markup but these are necessary and minimal. Using wrapper DIVs etc, as shown in the example template files, you can structure your blog however you want to fit in your new/existing site. Even the CSS and JS are demos! :-). In a nutshell, MarkupBlog does not come with its own CSS and JS. What is included is just meant to give you an idea of how to use it :-). In due course,  I will do a write-up of all the methods available in MarkupBlog and what they do.


As per above, it is not difficult to fit MarkupBlog into your existing site's structure. In fact, since it is a module, you can even call it wherever you wish, in whatever template files, even your existing ones. What I am saying is that you don't even have to use the example template files! You just need to know the parameters MarkupBlog methods expect and you are on your way. This may be a bit advanced for you at the moment, so you might want to instead edit the example files as much as you wish :D

Role and Permission

Note that Blog installs the role 'blog-author' and permission 'blog'. These are available to you to control access as you wish. They are not automatically applied to any user. With these, you can can control the finer details of your blog. 


Currently, the 'authors' tab/view only shows the count of 'published' posts per author. I'll soon update this, probably with a two different columns; one showing count of 'published' and the other showing count of 'pending [unpublished]' posts for each author. 

  • Like 3
Link to comment
Share on other sites

Hi kongondo,

I believe you are referring to these template files: blog-recent-comments; blog-recent-posts; and blog-recent-tweets.

No, I refered to my template files I set up for other purposes than the blog.

I think what you probably mean is that when you edit a post, the new post status is not reflected in the posts table.

Exactly, thanks for making this more clear.

After closing an edit modal (widgets, posts, tags, categories), the parent page now refreshes to reflect relevant changes

Super fast service!  ^-^

  • Like 1
Link to comment
Share on other sites

Hi kongondo,

No, I refered to my template files I set up for other purposes than the blog......

Thanks for clarifying. Fixed in the latest commit. I think the problem was that you have a page called widgets. The previous selector was looking for pages with a parent 'widgets'. Good catch! I have changed the selector to be more specific.

  • Like 1
Link to comment
Share on other sites

Follow-up to my post above about the 'example template files':

1. If you decide to hide some widgets (say recent posts), the HTML is still showing up and reporting 'no posts found'. That's just an oversight on my part. 'Unavailable' widgets should not even output their HTML; 'no posts found' should mean exactly that. I'll try to fix this later, but it is not a high priority :-)

2. On a related issue, you will need to install and configure MarkupTwitterFeed in order to use the example 'Twitter Widget'.


I have updated the example Template File 'blog-recent-tweets.php'. The references to some fields were wrong :-). Also updated the README + First Post.

Link to comment
Share on other sites

I love it when someone posts something as amazing as this! Another one where simply clicking 'Like' is nowhere near enough.

Thank you Kongondo, this is an exceptional contribution.

  • Like 2
Link to comment
Share on other sites

That's amazing - the very day I decided to put a blog on my site, this gets uploaded! Thank you so much! 

I've installed it and incorporated it into my site with surprising ease. 

The only issue I've had is with comment moderation - how do I do it? There's no option in the blog admin. 

EDIT: I found it - edit the post that the comment is on and the section for approving comments is at the bottom. Guess I should have watched the video tutorials! :)

  • Like 1
Link to comment
Share on other sites


Welcome to the forums! I'm glad the module is of benefit...

Currently, there is no comment moderation within Blog itself. This is deliberate. You have two choices:

1. You can install the module 'Comments Manager' to manage all your comments in one place. It would have been nice to integrate Blog and CM better but currently there are no plans to do so.

2. You can moderate comments on a per post basis. Just edit a post and you will find all comments awaiting your approval :-)

  • Like 2
Link to comment
Share on other sites

Great thanks! The comments manager is just what I was looking for. To make it it a bit more integrated I just moved the "Comments Manager" page from /admin/setup to /admin/blog, which doesn't seem to have caused any problems. 

A couple of things: to get widgets from the sidebar to display on non-blog pages, the module has to be called on every page:

//CALL THE MODULE - MarkupBlog
$blogOut = $modules->get("MarkupBlog");

I've just added it to the top of my sidebar.inc for the time being, I'll have to refactor my code a bit in the future to stop it being called twice on blog pages.

Second, to get posts to show only an excerpt, in the template files change the line:

$content .= $blogOut->renderPosts("limit={$limit}");


$content .= $blogOut->renderPosts("limit={$limit}", $small=true);

Currently it looks like the excerpt length is hardcoded to 450 characters - perhaps adding an option for people to set this themselves would be a good idea? In the meantime, for anyone that wants to change this, find the line 

$summary = strip_tags(substr($page->blog_body, 0, 450));

in MarkupBlog.module and set it to whatever you want. 

Great work, I'm getting more impressed the more time I spend with it! 

  • Like 2
Link to comment
Share on other sites


Thanks for further testing this.

One thing I have tried to clarify in my posts further up is that the included Template Files are just demos. Some of the code in there is not even related to MarkupBlog. The code in the Template Files is also deliberately verbose. For instance, there is a lot of repetitive code that could be best split up into includes. I decided to leave it like that so that users could select whatever templating approach they wanted (yes, refactoring needed; I might revisit this decision in future). In order to do this effectively, they need to be familiar with the methods/functions available in MarkupBlog :-). So, I will be writing up a guide covering those methods (e.g. your examples above). :D

Configurable Excerpt Length:

Good suggestion. Please file an issue on GitHub if you can so that I don't forget this.


  • Like 1
Link to comment
Share on other sites


Regarding blog_date field. I get the feeling it is designed to be the date/time that the blog post is published, but from what I can see it gets set when the post is first created and doesn't automatically change after that. I might be misunderstanding your use of the field, but I would like to see it change automatically when the post is published and not change after that - maybe even disable user editing of it?

I know we often draft up several posts at a time and publish them later. I don't think we should have to manually adjust this field when publishing the post.

Another thought for you - have you considered integrating this module:


or the functionality from it into the blog posts tab? This would make WP users feel at home. Thanks for considering.

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Similar Content

    • By monollonom
      (once again I was surprised to see a work of mine pop up in the newsletter, this time without even listing the module on PW modules website 😅. Thx @teppo !)
      Github: https://github.com/romaincazier/FieldtypeQRCode
      Modules directory: https://processwire.com/modules/fieldtype-qrcode/
      A simple fieldtype generating a QR Code from the public URL of the page, and more.
      Using the PHP library QR Code Generator by Kazuhiko Arase.

      In the field’s Details tab you can change between .gif or .svg formats. If you select .svg you will have the option to directly output the markup instead of a base64 image. SVG is the default.
      You can also change what is used to generate the QR code and even have several sources. The accepted sources (separated by a comma) are: httpUrl, editUrl, or the name of any text/URL/file/image field.
      If LanguageSupport is installed the compatible sources (httpUrl, text field, ...) will return as many QR codes as there are languages. Note however that when outputting on the front-end, only the languages visible to the user will be generated.
      Unformatted value
      When using $page->getUnformatted("qrcode_field") it returns an array with the following structure:
      [ [ "label" => string, // label used in the admin "qr" => string, // the qrcode image "source" => string, // the source, as defined in the configuration "text" => string // and the text used to generate the qrcode ], ... ] Formatted value
      The formatted value is an <img>/<svg> (or several right next to each other). There is no other markup.
      Should you need the same markup as in the admin you could use:
      $field = $fields->get("qrcode_field"); $field->type->markupValue($page, $field, $page->getUnformatted("qrcode_field")); But it’s a bit cumbersome, plus you need to import the FieldtypeQRCode's css/js. Best is to make your own markup using the unformatted value.
      Static QR code generator
      You can call FieldtypeQRCode::generateQRCode to generate any QR code you want. Its arguments are:
      string $text bool $svg Generate the QR code as svg instead of gif ? (default=true) bool $markup If svg, output its markup instead of a base64 ? (default=false) Hooks
      Please have a look at the source code for more details about the hookable functions.
      $wire->addHookAfter("FieldtypeQRCode::getQRText", function($event) { $page = $event->arguments("page"); $event->return = $page->title; // or could be: $event->return = "Your custom text"; }) $wire->addHookAfter("FieldtypeQRCode::generateQRCodes", function($event) { $qrcodes = $event->return; // keep everything except the QR codes generated from editUrl foreach($qrcodes as $key => &$qrcode) { if($qrcode["source"] === "editUrl") { unset($qrcodes[$key]); } } unset($qrcode); $event->return = $qrcodes; })
    • By Sebi
      AppApiFile adds the /file endpoint to the AppApi routes definition. Makes it possible to query files via the api. 
      This module relies on the base module AppApi, which must be installed before AppApiFile can do its work.
      You can access all files that are uploaded at any ProcessWire page. Call api/file/route/in/pagetree?file=test.jpg to access a page via its route in the page tree. Alternatively you can call api/file/4242?file=test.jpg (e.g.,) to access a page by its id. The module will make sure that the page is accessible by the active user.
      The GET-param "file" defines the basename of the file which you want to get.
      The following GET-params (optional) can be used to manipulate an image:
      width height maxwidth maxheight cropX cropY Use GET-Param format=base64 to receive the file in base64 format.
    • By MarkE
      This fieldtype and inputfield bundle was built for storing measurement values within a field, rendering them in a variety of formats and converting them to other units or otherwise modifying them via the API.
      The API consists of a number of predefined functions, some of which include...
      render() for rendering the measurement object, valueAs() for converting the value to another unit value, convertTo() for converting the whole measurement object to different units, and add() and subtract() for for modifying the stored value by the value (converted as required) in another measurement. In the admin the inputfield includes a checkbox (which can be optionally disabled) for converting values on page save. For an example if a value was typed in as centimeters, the unit was changed to metres, and the page saved with this checkbox selected, said value would be automatically converted so that e.g. 170 cm becomes 1.7 m.

      A simple length field using Fieldtype Measurement and Inputfield Measurement.
      Combination units (e.g. feet and inches) are also supported.
      Please note that this module is 'proof of concept' at the moment - there are limited units available and quite a lot of code tidying to do. More units will be added shortly.
      See the GitHub at https://github.com/MetaTunes/FieldtypeMeasurement for full details and updates.
    • By tcnet
      File Manager for ProcessWire is a module to manager files and folders from the CMS backend. It supports creating, deleting, renaming, packing, unpacking, uploading, downloading and editing of files and folders. The integrated code editor ACE supports highlighting of all common programming languages.

      This module is probably the most powerful module. You might destroy your processwire installation if you don't exactly know what you doing. Be careful and use it at your own risk!
      ACE code editor
      This module uses ACE code editor available from: https://github.com/ajaxorg/ace

      This module uses the JavaScript dragscroll available from: http://github.com/asvd/dragscroll. Dragscroll adds the ability to drag the table horizontally with the mouse pointer.
      PHP File Manager
      This module uses a modified version of PHP File Manager available from: https://github.com/alexantr/filemanager
    • By tcnet
      This module implements the website live chat service from tawk.to. Actually the module doesn't have to do much. It just need to inserted a few lines of JavaScript just before the closing body tag </body> on each side. However, the module offers additional options to display the widget only on certain pages.
      Create an account
      Visit https://www.tawk.to and create an account. It's free! At some point you will reach a page where you can copy the required JavaScript-code.

      Open the module settings and paste the JavaScript-code into the field as shown below. Click "Submit" and that's all.

      Open the module settings
      The settings for this module are located int the menu Modules=>Configure=>LiveChatTawkTo.

  • Create New...