|Current Version: 1.04
I much prefer to compose and edit text with my favorite text editor, rather than in a <textarea> box on a web page. Thus, I created the 'file-based posts' plugin for WordPress, which allows you to maintain the body of a post in a file on the local web-server host. Changes to the file are reflected immediately on the blog site.
- Install this plugin (download here and install as “file-based-posts.php” in your wp-content/plugins directory).
- On the newly-available “File-Based Posts” tab of the “Options” blog admin page, configure the directory in which post files will go. (Be sure the web server can read files in that directory.)
- In that directory, create a file containing the body content of your next post, say “my-next-post.html”. (The filename must end with .html, and may not contain whitespace.)
- With WordPress's “Write Post” browser-based interface, enter the post's title, date, draft/public, etc., as you normally would. However, instead of putting the full body content in the big <textarea> box, simply put “FILE: my-next-post.html” in that box.
- That's it. You may edit the “my-next-post.html” file any time; changes are pulled in the next time the post is viewed.
Start over from step #3 for your next post or page (using a unique filename, of course).
After first installing this plugin (see step one above), visit the Options admin page (“File-Based Posts” tab) to configure this plugin's base-directory parameter (the directory in which you'll create and maintain post-related files). From then on, as you create content with WordPress's “Write Post” and “Write Page” browser-based interface, you have the option of typing the full content in the <textarea> box as before, or, you can simply refer to the file which contains the content (the file having been previously created by you with your favorite text editor).
For example, you can create a file “my-next-post.html” (the filename must end with “.html”), and enter the body content of your post. You then use the normal WordPress mechanism to create a post, but instead of typing the post body content in the big <textarea> box, you need enter only “FILE:” followed by the filename (“my-next-post.html”). For example,
Be sure to fill in the title, date, visibility, etc., on the normal WordPress “Write Post” page. Only the body content is in the file.
Updating A Post
You may update the file at any time; any changes are reflected online the next time the post is viewed. If you wish to update the post's title, date, categories, custom fields, etc. (anything except the body), do so as with any WordPress post or page, via the browser-based admin interface.
The Post's “edit” Page
If you view the post's “edit” page in WordPress, you'll see something like:
The first line is the “FILE:” line you entered when the post was created, followed by a warning (inserted by this plugin) that any changes to the body content via this interface will be lost, since the body content is refreshed from the file, if needed, each time the post is viewed.
Following the warning, the body content most-recently-pulled from the file is shown.
Reverting A Post From File-Based Back To Normal
If you wish to move control of a post's body content from the file back to WordPress's database, simply view the post's “edit” page and remove the “FILE:” line (and the warning that this plugin added). What's left is the post content most recently pulled from the file, and that's what will stay in the database. The lack of a leading “FILE:” line means that this post has now been disassociated from this plugin and associated files. You can then safely go ahead and delete the file, if you wish, as it will no longer be used.
Any content of the file within
<nopost> . . . . . </nopost>
tags is removed before what remains is used for the post. This can be useful for “backdoor” testing of a page prior to posting.
If you choose to make your base directory one that's part of your web server's document tree, you can view files you've written (or are in the process of writing) as normal static web pages. I like to do this to preview a post before I bother to integrate it with WordPress. However, in order to get a more true rendition of what it'll look like once in my blog, I need to include the style sheet link. I include that link within <nopost> ... </nopost> tags so that the extra link doesn't actually become part of the post once I do integrate it with WordPress. (I don't want to just remove the link prior to posting, since I'd like to keep it there for when I test later edits.)
[ This documentation is correct and up to date, but the documentation has expanded more quickly than my ability to organize it well, so my apologies for the disorganized presentation ]
You can include the contents of other files in your post file with the
directive. (The file is read from the same directory as other file-based-post files)
As a guard against an infinitely-recursive include, there is a limit to how deep the include nesting can go (currently 8), which is wildly larger than will ever be needed, I think.
I also use the include feature to include advertisements by Yahoo!. This is what I put in the post where I want the ads to appear:
<fbp_include once: ADS.html>
Note the location of the colon -- it's easy to get in the wrong spot.
The ADS.html file contains the call to Yahoo! to insert the ads. I have only one such call per post, but some pages (such as the blog home page) can display multiple posts. Since I don't want multiple ad calls, I use the once attribute to have only the first include actually happen.
The “abort if already included” check happens only with a <fbp_include> that has the once attribute. Even after including the file this way, a subsequent include without the once attribute does actually include the file, since it wasn't told to check.
Including one from among a group of files
Let's say that some posts want ads on the right (via Ads-Right.html), on the left (Ads-Left.html), or as a banner (Ads-Top.html). Even if these files are included into each post with the once attribute, you'll still get multiple includes when these includes are mixed and matched on one page, since the filenames being included are distinct.
To solve this problem, you must tell each <fbp_include> that the file being included is part of a group. This is done with the radio attribute (think <input type='radio'>). Here's how the three includes might appear:
<fbp_include once radio=ads: Ads-Left.html> <fbp_include once radio=ads: Ads-Right.html> <fbp_include once radio=ads: Ads-Top.html>
The radio=ads tells the plugin to consider the name, for counting purposes, to be “ads”. Thus, only the first of the three will actually be included.
The order of attributes (in this case radio=ads and once) is not relevant.
Passing along variables with the include
An included file may contain references such as
<fbp_var default='value': name>
These insert the value of the named variable, which itself had been set via something like:
<fbp_include once set background = 'white': ADS.html>
Note that no variables exist until you create them in a <fbp_include> directive.
Here's a snippet from ADS.html:
The <fbp_var> directive is replaced by the value of the background variable, which was set to “white” in the above <fbp_include> example. If that variable hadn't been set (such as by the simple call <fbp_include once: ADS.html>), the default value CDCDCD is used. The default default is an empty string.
You can also indicate that if a variable hasn't been set, use the value of another variable (or the first from among a list of variables which has a value). This is done with the fallback attribute, which contains a comma-separated list of variable names. As a simple (contrived) example, consider an include to display an image. It expects that the url and caption variables be set, and, optionally, an alt variable (for the alt text):
<img src="<fbp_var: url>" alt="<fbp_var fallback='caption,url': alt>"> <br/> <fbp_var: caption>
In the request of for the alt variable, the fallback='caption,url' indicates that if alt has not been given a value, use the caption variable (if it has a value), or the url variable (if it has one).
If the requested variable has no value, and none of the fallback variables has a value, the default (via the default attribute) is used, or if no default, an empty string.
You may have multiple set components to an include:
<fbp_include once set background = 'white', set foreground = "red": ADS.html>
Don't forget to repeat the “set” keyword for each variable. The comma between the settings is optional, but helps make it read more easily.
Currently, there's no way to set a variable outside of an <fbp_include> directive, nor a way to clear variables. I can add these features if there's a need for them.
Other Include Options
If you use the raw attribute with an include, the read file is injected directly, without any parsing. (<nopost>, other includes, and variable references, for example, are not recognized.)
The cooked include attribute is similar to raw, except that the text is cooked for html ('&' is replaced by '&', etc.).
The uncounted include attribute indicates that the file is unconditionally included, but not counted as having been included (so that a subsequent include of the same file with the once attribute does succeed). The uncounted attribute is particularly useful with cooked. (See this post for an example.)
There's a simple debugging mechanism built into this plugin. On the options page for this plugin (where the posts directory is configured), you can set the ID of the post you wish to debug. When that number is set and you view the post while logged in as someone allowed to edit the post, you'll see at the top various messages.
For example, consider my post on raising a bilingual child, which is post #88 of my blog, after having entered “88” as the ID on the options page, I see the following:
[file-based-posts: about to inspect post #88 data in WordPress database]
[file-based-posts: data begins: FILE:·bilingual.html\n\n<!--\n***********************
[file-based-posts: fbp_process_one_file(level is 1, file is “/jfriedl/blog/posts/bilingual.html”)]
[file-based-posts: read 8972 bytes]
[file-based-posts: include of 'ADS.html', option string 'once']
[file-based-posts: include of ADS.html, option 'once' has value '1']
[file-based-posts: fbp_process_one_file(level is 2, file is “/jfriedl/blog/posts/ADS.html”)]
[file-based-posts: read 409 bytes]
[file-based-posts: new content for level 2 is 409 bytes]
[file-based-posts: new content for level 1 is 9100 bytes]
[file-based-posts: content has not changed; leaving WordPress database as is]
Anthony turns three years old tomorrow. He’s been talking up a storm for quite some time, but he’s behind other kids his age. It’s not something we’re concerned about because, if he’s got, say, 70% of the language skills as his peers, he’s really got 140% of the skills (70% English + 70% Japanese). I know of other kids who have three or four languages — a kid’s brain is just amazing.
blah blah blah.....
If you set the debug ID to -1 (minus one), debugging is turned on for all posts.
Issues To Be Aware Of
When configuring the directory for post-related files, be sure that such files are editable by you, and readable by the web server.
File updates are incorporated when the blog content is viewed (such as by a user with a browser, or via a full-content RSS feed being pulled). This provides for one small “gotcha” which you should be aware of: edits to a post file do not become visible to WordPress's “Blog Search” feature until the related post has been viewed. In practice this is a minor nit, as you'll normally immediately view the post yourself to confirm that the changes look okay.
The “FILE: my-next-post.html” used to refer to each post's filename becomes part of the post's content with respect to WordPress's “Search” feature. Thus, for example, a user searching for “file html” would see all your file-based posts and not understand why.
If the “FILE:” line suddenly appears at the top of a post (when viewing your blog as a reader would), it means that the post's file was not accessible (either because it's been moved or removed, or perhaps due to changed permissions). In such cases, the content that had been most recently read from the file (and hence most-recently saved in WordPress's database) is displayed, albeit along with the “FILE:” line. (There is a good argument to be made that the “FILE:” line should not be shown in this failure mode, but I choose to show it simply as an easily-seen indication that there is a failure.)
To help debug why you see the “FILE:”, see the debugging section above.
The author is not particularly familiar with WordPress's (convoluted and under-documented) internals.
|1.04||11-Nov-2005||Changed uses of ' to ', since it seems that IE doesn't support &apos. Sighh.|
|1.03||30-Oct-2005||Added the radio, raw, cooked, and uncounted attributes to <fbp_include>
Added the fallback, singlequoted, and doublequoted attributes to <fbp_var>.
|1.02||29-Oct-2005||Added <fbp_include> and <fbp_var> directives.
Allowed a debugging id of -1 to mean “debug all posts”
|1.01||24-Sep-2005||Made debugging messages invisible except to logged-in users who are allowed to edit the post. That way, random readers don't see your debugging cruft.|
Feedback appreciated, via a comment below, or via email.