Don’t be fooled by the title: this text covers the implementation of an entire, expandable, client-side content material administration system utilizing REBOL. This technique makes it straightforward for any web site operator, no matter expertise, to replace website content material whereas maintaining markup legitimate and constant and making certain that hyperlinks keep pertinent.
Article Continues Beneath
Why one other CMS? I’m not a fan of the client-side content material administration supplied by FrontPage or Dreamweaver, and server-based programs depend on server OS and software program and are susceptible to the restrictions of internet hosting packages. This CMS will work on any desktop system.
Your content material editors will want to have the ability to modify a textual content file, perceive just a few markup guidelines, and will have slightly double-clicking expertise.
You, the online designer and supplier of code, ought to have slightly scripting expertise and a replica of the scripting language REBOL. The core language runs on over 40 platforms and is on the market from their downloads part. To run the code on this article, you simply must observe the set up directions in your platform, which is normally no extra arduous than unpacking a Zip file.
REBOL could also be new to a lot of you, so I’d recommend a fast take a look at among the wonderful language primers on their website, although you could discover it simply as straightforward to study by instance.
All content material in your website is saved inside a single textual content file, which I’ll title content material.txt. This file makes use of simplified markup guidelines I’ve outlined myself, and the contents of the file will look one thing like what’s under. (Observe: Some traces have been wrapped to suit this web page. View the linked doc for simpler examine and higher accuracy.)
Website Title: Enterprise, Inc.New Web page: Merchandise (merchandise.html)===Enterprise, Inc. ProductsBusiness, Inc. has an **wonderful** popularity
on this planet of workplace provides. Our specialties
embrace:...Paper Clips...Staples...Pen HoldersBuy on-line: ##http://oursite/retailer/##Enterprise, Inc. Retailer##.
This simplified markup (which you outline) is all of the content material editors want to make use of to maintain their website up-to-date. Observe: each declaration, heading and paragraph is on a single line, so a word-wrapping textual content editor is a should.
On the high of the file is the title of the location – it will seem between the <title>
tags. Headers are outlined by ===
(three equals indicators) in the beginning of the road, lists by ...
, and each different line is a daily paragraph. Inline formatting contains wrapping some textual content with two **
s to emphasise it and hyperlinks go ##
url ##
textual content ##
. I even have particular markup for photographs, although it’s past the scope of this text to elucidate their implementation. Evidently, it probes the picture for its measurement attributes.
One script matches all#section4
To start the REBOL script, first we have to create a textual content file known as content-management.r (or something ending in .r). On the high of the file goes:
REBOL [ author: "Christopher Ross-Gill" rights: "Chris and ALA readers" ]
The REBOL header gives a lot scope for describing your scripts.
Now we are able to load within the content material.
content-block: learn/traces %content material.txt
I’ve used the /traces
refinement of learn
to separate the file by line endings (file names in REBOL have a ‘%’ prefix and use ‘/’ for directories – it doesn’t matter what the platform). We’ll find yourself with a block (like an array) of strings. We simply must zap all empty strings from content-block
. {Line wraps are marked thusly: ». – Ed.}
whereas [empty-string: find content-block ""]»
[remove empty-string]
Parsing the content material#section5
Extracting construction from our doc is made straightforward with the parse
command. This subsequent little bit of code defines construction
as an empty block, then loops by means of content-block
exposing every string to the trials of the parse
rule, filling construction
with the processed, organized content material.
construction: copy []foreach paragraph content-block [ parsed?: parse paragraph [ "Site Title:" copy para to end (repend structure ['site-title trim para]) | "New Web page:" copy para to "(" skip copy id to ")" skip (repend construction ['h1 trim para id]) | "===" copy para to finish (repend construction ['h2 para]) | "..." copy para to finish (repend construction ['li para]) ] if not parsed? [repend structure ['p paragraph]] ]
Notes on the principles: In REBOL, a parse rule not solely describes the construction of a string, it additionally instructs this system what to do with the extracted values – these directions are saved within the parentheses.
Taking the primary rule for example, it seems to be in the beginning of the string for the textual content “Website Title: “
then units the phrase (like a variable) para
to the remainder of the string. It then appends the construction with the phrase site-title
and the string para
. Alternate guidelines are separated by the |
character. If not one of the guidelines match, we append the string with the phrase p
. The construction
block ought to look one thing like this (for extra advanced strings, REBOL makes use of curly brackets {}
):
[
site-title "Business, Inc."
h1 "Products" "products.html"
h2 "Business, Inc. Products"
p {Business, Inc. has an excellent reputation
in the world of office supplies. Our specialties include:}
li "Paper Clips"
li "Staples"
li "Pen Holders"
p {Buy online – »
##http://oursite/store/##Business, Inc. Store##.}
]
Inline formatting#section6
Earlier than we go punching our content material into an XHTML template, we’ll arrange a paragraph formatter. This perform offers with punctuation, particular characters, hyperlinks and emphasis.
format-text: func [text [string!]][ replace/all text {&} {&} replace/all text { "} { “} if (first text) = #"^"" » [replace text {"} {“}] change/all textual content {"} {”} change/all textual content { '} { ‘} if (first textual content) = #"'" » [replace text {'} {‘}] change/all textual content {'} {’} change/all textual content {--} {–} change/all textual content { – } {–} change/all textual content {. } {. }
The gathering above of change
s offers us curly quotes, em dashes, et al.
parse/all textual content [ any [ thru {##} copy link to {##} 2 skip copy hlink to {##} ( href: {<a href="} nlink: link replace text rejoin [ {##} link {##} hlink {##} ] rejoin [ href lowercase copy nlink{} hlink {</a>} ] ) ] to finish ]
This parse
rule might be extra difficult, e.g. it may possibly detect e mail addresses and exterior hyperlinks. The any
in the beginning of the rule signifies that there could also be none or extra hyperlinks inside a paragraph (versus some
which might suggest a number of hyperlinks).
parse/all textual content [ any [ thru {**} copy emphasized to {**} ( replace text rejoin [ {**} emphasized {**} ] rejoin [ {<em>} emphasized {</em>} ] ) ] to finish ]
An easier model of the hyperlink rule.
change/all textual content {@} {@}
As an anti-spam measure, this replaces the ‘@’ image with its related entity reference quantity.
return textual content ]
Thus concludes the format perform.
Your XHTML template#section7
The template might be taken care of simply. Put together your XHTML doc and reserve it as template.html, placing placeholders for the web page title and the physique. A minimal template is under. The linked doc is invisible in your browser till you view supply, which ought to appear to be this:
<html><head>» title></title></head> <physique><% page-body » %></physique></html>
Placeholders want solely be distinctive in development; they don’t essentially must be an XHTML tag.
punch-template: func [ site-title [string!] page-title [string!] page-menu [string!] page-content [string!] ][ template: read %template.html replace template <% page-title » %> rejoin [site-title ": " page-title] change template <% page-body » %> rejoin [newline page-menu newline page-content newline] return template ]
That’s our perform to exchange the placeholders. Yep, it’s that easy.
Placing all of it collectively#section8
So let’s evaluation what we’ve got thus far: content material, saved as construction
; formatting tips, saved within the perform format-text
; and a template, saved within the perform punch-template
. To place all the things collectively, we have to add two extra shops to our script: one for particular person web page contents with related file names, and a string to retailer the thực đơn code.
pages: copy [] thực đơn: copy ""
Now we are able to wrap up the content material from inside a single parse
rule – keep in mind, code might be run from parentheses inside a parse rule. Since we’re parsing a block versus a string this time, the rule seems to be barely totally different:
parse construction [ (append menu <div id="menu">) 'site-title set title string!
Remember the structure
block? Our parse rule is stating that it must begin with the word site-title
followed by a string.
some [ 'h1 set header string! set id string! ( repend menu [ newline <p> build-tag compose [ a href (id) ] format-text header </a> </p> ] content material: copy "" repend content material [ newline <div id="content"> newline <h1> format-text header </h1> ] checklist?: false )
After we come throughout an h1
, we’re actually defining a brand new web page. So we add a reference to the thực đơn. Then we make a brand new string for this web page and insert a <div id=“content material”>
. Then we paste within the heading. The ultimate process is to show the checklist?
flag off. We’ll come to this quickly.
some [ 'h2 set para string! ( if list? [append content </ul> » list?: false] repend content material [newline <h2> » format-text para </h2>] ) | 'p set para string! ( if checklist? [append content » </ul> list?: false] repend content material [newline <p> span class="linewrap">» format-text para </p>] ) | 'li set para string! ( if not checklist? [repend content » [newline <ul>] checklist?: true] repend content material [newline <li> » format-text para </li>] )
This covers the remainder of the formatting. checklist?
permits us to examine when we’ve got so as to add the <ul>
tag. After we come throughout an li
and checklist?
shouldn’t be true
, we set checklist?
to true
and add a <ul>
. Likewise, if checklist?
is true
after we come throughout a header or paragraph, we insert the </ul>
tag and set checklist?
to false
.
] ( if checklist? [append content </ul>] append content material </div> repend pages [to-file id content] ) ] (append thực đơn </div>) ]
That ought to fill our pages
block and thực đơn
string properly.
To complete up, we simply loop by means of the pages
block, and all the things we have to put the location collectively is there. REBOL treats information and ftp urls in the identical approach, so you might fairly simply change %pages/
with ftp://person:[email protected]/pages/
to put in writing the pages on to your net server – the whole content material administration system.
if not exists? %pages/ [make-dir %pages/]foreach [file content] pages [
write join %pages/ file punch-template »
title header menu content
]
Save the script. Place in the identical folder as content material.txt
and template.html
and execute the script. A brand new folder known as pages
will seem, containing, if you happen to adopted my instance, merchandise.html
. Strive including new pages to content material.txt
or strive including your personal formatting guidelines.
This script can kind the bottom of a way more highly effective and sophisticated client-side content material administration system. Extra advanced formatters exist in REBOL, reminiscent of Make-Doc-Professional or the HTML Dialect. An article on how REBOL blocks work is on the market at REBOL Forces.