About the author
In the feedback to the Blog to the Future post, Dan and Robert, two fellow bloggers and Delphi developers, commented,
“Very cool. Care to elaborate on how you set this up? Home-grown app? I've been thinking about doing this for my blog, too. Thanks.” and “what did you have to change to pull this off?”
in reference to how I set up scheduled publishing.
So, Dan and Robert, in answer to your question, I wrote this article to elaborate. ;o) And yes, it's a home-grown app, since .Text does not yet have this ability, and I'm a developer.
(Other articles in the .Text development / enhancement series by me)
In order to understand scheduled publishing, it is necessary to look at the Blog_Content table of your .Text database. The PostConfig column controls whether a post is accessible to the public or not. Specifically, bit 0 when set to 0, tells .Text that the post is not published. When set to 1, the post is published.
In order for scheduled publishing to work for me, I had to change some of my habits. First, I went to Options / Preferences, and set “Always create new items as Published” to No. What this meant was that, whenever I write a new article, that article is not published. At the same time, I also set “Always expand advanced options” to Yes. This gave me the option and flexibility such that if I were to write a new article, and I decide to publish it immediately, all I have to do is scroll down a bit, and check the “Published” checkbox.
Next, I wrote an application that queries for all rows in which the PostConfig column's bit 0 is 0, plus some other conditions. If the conditions were satisfied, I then toggle the value of bit 0. I also updated the DateAdded, and DateUpdated columns so that it represents the date/time of the published article.
I then created a task schedule that runs the application every day at 7am.
The publishing code was quite an ugly hack. BTW, if you run into any problems, lemme know.
procedure TDataModule1.PublishBlog(const BlogID: Integer);var Year, Month, Day: Word; strDT, SQL: string; DT: TDatetime; DTS: TSQLTimeStamp;begin try SQLConnection1.Open; qryBlog.SQL.Text := Format('SELECT * ' + 'FROM blog_Content ' + 'WHERE (PostConfig & 1 = 0) AND (FeedBackCount = 0) '+ 'AND (BlogID = %d) AND (DateAdded >= ''4/May/2004'')', [BlogID]);
qryBlog.Open; if qryBlog.RecordCount > 0 then begin // Only once! DT := Today; DecodeDate(DT, Year, Month, Day); DT := EncodeDateTime(Year, Month, Day, 7, 0, 0, 0); DTS := DateTimeToSQLTimeStamp(DT); SQL := 'UPDATE blog_Content SET PostConfig = :PostConfig, '+ 'DateAdded = :DateAdded, DateUpdated = :DateUpdated where ID = :ID'; qryUpdate.SQL.Text := SQL; qryUpdate.ParamByName('PostConfig').AsInteger := qryBlogPostConfig.AsInteger or 1; qryUpdate.ParamByName('DateAdded').AsSQLTimeStamp := DTS; qryUpdate.ParamByName('DateUpdated').AsSQLTimeStamp := DTS; qryUpdate.ParamByName('ID').AsInteger := qryBlogID.AsInteger; qryUpdate.ExecSQL; EventLog.LogMessage(Format('Blog update for ID: %d, BlogID: %d successful!', [qryBlogID.AsInteger, BlogID])); end else begin EventLog.LogMessage(Format('No blogs to update for BlogID = %d', [BlogID])); end; except on E: Exception do EventLog.LogMessage(E.Message); end;end;
A method pointer is now the same as a global procedure, ie, procedure of object = procedure.