YurtCMS 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +18 -0
- data/bin/yurt +282 -0
- data/lib/yurtcms.rb +175 -0
- data/site/content/index +14 -0
- data/site/htdocs/includes/content/index.html +11 -0
- data/site/htdocs/includes/content/index.metatags.html +1 -0
- data/site/htdocs/includes/template.html +22 -0
- data/site/htdocs/includes/template.metatags.html +4 -0
- data/site/htdocs/index.html +2 -0
- data/site/htdocs/media/css/styles.css +106 -0
- data/site/htdocs/media/images/admin_bg.gif +0 -0
- data/site/htdocs/media/images/admin_head.jpg +0 -0
- data/site/htdocs/media/images/directory.png +0 -0
- data/site/htdocs/media/images/file.png +0 -0
- data/site/htdocs/media/images/pane_bg.gif +0 -0
- data/site/htdocs/media/js/prototype.js +1781 -0
- data/site/log/access.log +0 -0
- data/site/log/error.log +0 -0
- data/site/yurt/index.html +135 -0
- data/site/yurt/media/css/styles.css +155 -0
- data/site/yurt/media/images/admin_bg.gif +0 -0
- data/site/yurt/media/images/admin_head.jpg +0 -0
- data/site/yurt/media/images/directory.png +0 -0
- data/site/yurt/media/images/file.png +0 -0
- data/site/yurt/media/images/pane_bg.gif +0 -0
- data/site/yurt/media/js/prototype.js +1781 -0
- data/site/yurt/yurt.cgi +250 -0
- data/site/yurt.conf +53 -0
- data/test/cms_filesystem.rb +111 -0
- data/test/cms_strings.rb +132 -0
- metadata +106 -0
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
== Welcome to Yurt CMS
|
2
|
+
|
3
|
+
Yurt CMS is a content management system designed for web developers who create
|
4
|
+
mostly static web sites. In building this software, I tried to realize the
|
5
|
+
following key features:
|
6
|
+
|
7
|
+
* No Database: Content for mostly static sites should reside in editable
|
8
|
+
files, not databases.
|
9
|
+
* Version Control System Friendly: The web site should be easy to store
|
10
|
+
in a revision control system.
|
11
|
+
* Two-step deployment: Starting a new website should be as easy as running a
|
12
|
+
single command in the console and updating your webserver configuration.
|
13
|
+
* One-step go-live: Yurt CMS websites can be deployed simply by rsync'ing or
|
14
|
+
copying from the preview webroot to the live webroot.
|
15
|
+
* Web-based *and* console-based admin interfaces: Work where you're most
|
16
|
+
comfortable!
|
17
|
+
|
18
|
+
|
data/bin/yurt
ADDED
@@ -0,0 +1,282 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
|
4
|
+
# == Synopsis
|
5
|
+
#
|
6
|
+
# A simple commandline tool for basic site management
|
7
|
+
#
|
8
|
+
# == Usage
|
9
|
+
#
|
10
|
+
# yurt newsite foldername [port] <- creates a new directory structure for a
|
11
|
+
# Yurt CMS site, with a preconfigured
|
12
|
+
# apache conf file
|
13
|
+
# yurt newfile path/to/file <- creates a new content file
|
14
|
+
# yurt update [path/to/file] <- updates yurt infrastructure to latest
|
15
|
+
# version. path/to/file is optional if you're
|
16
|
+
# in the top level directory of your yurt
|
17
|
+
# install
|
18
|
+
# yurt newpartial path/to/file <- creates a new partial content file
|
19
|
+
# yurt generate path/to/file <- generates html from supplied content file
|
20
|
+
# yurt delete path/to/file <- deletes content file and html files
|
21
|
+
#
|
22
|
+
# == Author
|
23
|
+
#
|
24
|
+
# Robert Hahn <yurt_at_roberthahn_dot_ca>
|
25
|
+
#
|
26
|
+
# == Copyright
|
27
|
+
#
|
28
|
+
# Copyright (c)2006 Robert Hahn. Licensed under the same terms as the Camping framework
|
29
|
+
#
|
30
|
+
|
31
|
+
require File.dirname( __FILE__ ) + "/../lib/yurtcms"
|
32
|
+
require 'rdoc/usage'
|
33
|
+
require 'rbconfig.rb'
|
34
|
+
include Config
|
35
|
+
|
36
|
+
# this is needed to support the generate() function
|
37
|
+
class Hash
|
38
|
+
def method_missing(methID)
|
39
|
+
self[methID.id2name]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
def newsite yurt_root, port
|
46
|
+
# create directory
|
47
|
+
Dir.mkdir yurt_root
|
48
|
+
|
49
|
+
# copy template from CONFIG["datadir"]/yurt/dir_template.zip
|
50
|
+
source_files = Dir.glob( File.dirname( __FILE__ ) + "/../site/**/*" )
|
51
|
+
|
52
|
+
source_files.each do |sf|
|
53
|
+
local_f = [ yurt_root, sf.gsub( /^.*?site\//, "" ) ].join( "/" )
|
54
|
+
case File.stat( sf ).ftype
|
55
|
+
when "directory"
|
56
|
+
Dir.mkdir local_f
|
57
|
+
File.chmod( 0777, local_f )
|
58
|
+
when "file"
|
59
|
+
source = File.read( sf )
|
60
|
+
|
61
|
+
# if the file we read in is yurt.conf, we need to modify it to point to the web root.
|
62
|
+
if File.basename( sf ) == "yurt.conf"
|
63
|
+
source.gsub!( /<%= port %>/, port )
|
64
|
+
source.gsub!( /<%= yurt_root %>/, yurt_root )
|
65
|
+
local_f.gsub!( /yurt\.conf/, File.basename( yurt_root ) + ".conf" )
|
66
|
+
end
|
67
|
+
|
68
|
+
writefile( source,local_f )
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# write out a preferences file
|
73
|
+
|
74
|
+
writefile( "yurt_root: " + yurt_root, yurt_root + "/yurt.prefs" )
|
75
|
+
end
|
76
|
+
|
77
|
+
def update yurt_root
|
78
|
+
|
79
|
+
# copy template from CONFIG["datadir"]/yurt/dir_template.zip
|
80
|
+
source_files = Dir.glob( File.dirname( __FILE__ ) + "/../site/yurt/**/*" )
|
81
|
+
|
82
|
+
source_files.each do |sf|
|
83
|
+
local_f = [ yurt_root, sf.gsub( /^.*?site\//, "" ) ].join( "/" )
|
84
|
+
case File.stat( sf ).ftype
|
85
|
+
when "directory"
|
86
|
+
begin
|
87
|
+
Dir.mkdir local_f
|
88
|
+
rescue SystemCallError => e
|
89
|
+
unless e.errno == Errno::EEXIST::Errno
|
90
|
+
exit
|
91
|
+
end
|
92
|
+
end
|
93
|
+
File.chmod( 0777, local_f )
|
94
|
+
when "file"
|
95
|
+
source = File.read( sf )
|
96
|
+
writefile( source,local_f )
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def writefile sf_str, df
|
102
|
+
File.open( df, "w" ) do |dest|
|
103
|
+
dest.puts sf_str
|
104
|
+
end
|
105
|
+
File.chmod( 0777, df )
|
106
|
+
end
|
107
|
+
|
108
|
+
def normalize_path path
|
109
|
+
# This wasn't something that could easily be done, as I realized there was
|
110
|
+
# a number of situations that could legitimately occur. The following comment
|
111
|
+
# block will describe the logic required:
|
112
|
+
#
|
113
|
+
# 1. Is the supplied #{ path } absolute (begins with "/")?
|
114
|
+
#
|
115
|
+
# - if 1., then test 2.
|
116
|
+
# - if not 1., compute final path by concatenating cwd to #{ path }, call it
|
117
|
+
# full_path, then test 2.
|
118
|
+
|
119
|
+
if path[0,1] != "/"
|
120
|
+
# it's a relative path
|
121
|
+
path = [ Dir.getwd, path ].join( "/" )
|
122
|
+
end
|
123
|
+
|
124
|
+
# 2. Can I chdir to full_path?
|
125
|
+
#
|
126
|
+
# - If 2., getwd, then use it to locate yurt.prefs, then test 3.
|
127
|
+
# - If not 2, raise an error (destination not valid)
|
128
|
+
|
129
|
+
begin
|
130
|
+
Dir.chdir( File.dirname( path ) )
|
131
|
+
path = [ Dir.getwd, File.basename( path ) ].join( "/" )
|
132
|
+
rescue Exception => e
|
133
|
+
puts e.message
|
134
|
+
exit 1
|
135
|
+
end
|
136
|
+
|
137
|
+
# The following yield statement allows for implementation-specific tests to
|
138
|
+
# validate the path
|
139
|
+
yield path if block_given?
|
140
|
+
|
141
|
+
return path
|
142
|
+
end
|
143
|
+
|
144
|
+
def find_yurt_pref full_path
|
145
|
+
fp = full_path
|
146
|
+
yurt_root = nil
|
147
|
+
if File.exists? [ fp, "yurt.prefs" ].join( "/" )
|
148
|
+
yurt_root = fp
|
149
|
+
else
|
150
|
+
puts fp
|
151
|
+
while fp.include? "/content"
|
152
|
+
fp = fp.gsub( /content\/.*?$/, "" )
|
153
|
+
if File.exists? [ fp, "yurt.prefs" ].join( "/" )
|
154
|
+
yurt_root = fp
|
155
|
+
break
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
return yurt_root
|
161
|
+
end
|
162
|
+
|
163
|
+
def newfile path
|
164
|
+
# create file
|
165
|
+
File.open( path, "w" ) do |f|
|
166
|
+
f.puts "---"
|
167
|
+
f.puts "template: template.html"
|
168
|
+
f.puts "title: enter page title"
|
169
|
+
f.puts "description: enter page meta description content"
|
170
|
+
f.puts "keywords: enter keywords here"
|
171
|
+
f.puts "content: |-"
|
172
|
+
f.puts " Enter your content here. Please ensure that you begin each new line with two spaces while in this area."
|
173
|
+
end
|
174
|
+
File.chmod( 0777, path )
|
175
|
+
end
|
176
|
+
|
177
|
+
def newpartial path
|
178
|
+
# create file
|
179
|
+
File.open( path, "w" ) do |f|
|
180
|
+
f.puts "---"
|
181
|
+
f.puts "partial: yes"
|
182
|
+
f.puts "content: |-"
|
183
|
+
f.puts " Enter your content here. Please ensure that you begin each new line with two spaces while in this area."
|
184
|
+
end
|
185
|
+
File.chmod( 0777, path )
|
186
|
+
end
|
187
|
+
|
188
|
+
def get_yurt_path_pieces path
|
189
|
+
path = normalize_path path do |p|
|
190
|
+
# Is the computed path in #{ yurt_root }/content, and does a yurt.prefs file exist?
|
191
|
+
unless ( p.include? "/content" ) && find_yurt_pref( p )
|
192
|
+
puts "Not a valid yurt CMS web path - the file must be in /content, and a yurt.prefs file must be present."
|
193
|
+
exit 1
|
194
|
+
end
|
195
|
+
# are we about to generate a file?
|
196
|
+
#unless File.exists?( p ) && File.ftype( p ) == "file"
|
197
|
+
# puts "Not a valid yurt CMS file. If you need to generate a file, please check your path."
|
198
|
+
# exit 1
|
199
|
+
#end
|
200
|
+
end
|
201
|
+
|
202
|
+
yurt_root = find_yurt_pref( path )
|
203
|
+
|
204
|
+
file_to_generate = path
|
205
|
+
file_to_generate[ yurt_root + "content/" ] = ''
|
206
|
+
return [ yurt_root, file_to_generate ]
|
207
|
+
end
|
208
|
+
|
209
|
+
def generate yurt_root, file_to_generate
|
210
|
+
y = YurtCMS.new( yurt_root )
|
211
|
+
|
212
|
+
y.write_all_files( y.get_file_metadata( file_to_generate ) )
|
213
|
+
end
|
214
|
+
|
215
|
+
def delete yurt_root, file_to_generate
|
216
|
+
y = YurtCMS.new( yurt_root )
|
217
|
+
y.delete( file_to_generate )
|
218
|
+
end
|
219
|
+
|
220
|
+
def mkdir yurt_root, file_to_generate
|
221
|
+
y = YurtCMS.new( yurt_root )
|
222
|
+
y.make_new_dir( File.dirname( file_to_generate ), File.basename( file_to_generate ) )
|
223
|
+
end
|
224
|
+
|
225
|
+
case
|
226
|
+
when ARGV[0] == "newsite"
|
227
|
+
# check for and collect folder name
|
228
|
+
yurt_root = normalize_path ARGV[ 1 ]
|
229
|
+
|
230
|
+
port = "9878"
|
231
|
+
port = ARGV[ 2 ] if ARGV[ 2 ] && ARGV[ 2 ].match( /^\d*$/ )
|
232
|
+
|
233
|
+
newsite( yurt_root, port )
|
234
|
+
when ARGV[0] == "update"
|
235
|
+
if ARGV[ 1 ]
|
236
|
+
yurt_root = find_yurt_pref ARGV[ 1 ]
|
237
|
+
else
|
238
|
+
yurt_root = find_yurt_pref Dir.getwd
|
239
|
+
end
|
240
|
+
update yurt_root
|
241
|
+
when ARGV[0] == "newfile"
|
242
|
+
# check for a path/to/file
|
243
|
+
path = normalize_path ARGV[ 1 ] do |p|
|
244
|
+
# Is the computed path in #{ yurt_root }/content, and does a yurt.prefs file exist?
|
245
|
+
unless ( p.include? "/content" ) && find_yurt_pref( p )
|
246
|
+
puts "Not a valid yurt CMS web path - the file must be in /content, and a yurt.prefs file must be present."
|
247
|
+
exit 1
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
newfile( path )
|
252
|
+
when ARGV[0] == "newpartial"
|
253
|
+
# check for a path/to/file
|
254
|
+
path = normalize_path ARGV[ 1 ] do |p|
|
255
|
+
# Is the computed path in #{ yurt_root }/content, and does a yurt.prefs file exist?
|
256
|
+
unless ( p.include? "/content" ) && find_yurt_pref( p )
|
257
|
+
puts "Not a valid yurt CMS web path - the file must be in /content, and a yurt.prefs file must be present."
|
258
|
+
exit 1
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
newpartial( path )
|
263
|
+
when ARGV[0] == "generate"
|
264
|
+
# check for a path/to/file
|
265
|
+
yurt_root, file_to_generate = get_yurt_path_pieces( ARGV[1] )
|
266
|
+
|
267
|
+
generate( yurt_root, file_to_generate )
|
268
|
+
when ARGV[0] == "mkdir"
|
269
|
+
# check for a path/to/file
|
270
|
+
yurt_root, file_to_generate = get_yurt_path_pieces( ARGV[1] )
|
271
|
+
|
272
|
+
mkdir( yurt_root, file_to_generate )
|
273
|
+
when ARGV[0] == "delete"
|
274
|
+
# check for a path/to/file
|
275
|
+
yurt_root, file_to_generate = get_yurt_path_pieces( ARGV[1] )
|
276
|
+
|
277
|
+
delete( yurt_root, file_to_generate )
|
278
|
+
else
|
279
|
+
RDoc::usage
|
280
|
+
end
|
281
|
+
|
282
|
+
|
data/lib/yurtcms.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class YurtCMS
|
5
|
+
attr_reader :data_store, :web_root, :includes, :metatags, :partial, :ext
|
6
|
+
def initialize yurt_root
|
7
|
+
require 'rubygems'
|
8
|
+
require_gem 'BlueCloth'
|
9
|
+
|
10
|
+
@yurt_root = sanitize_path( yurt_root )
|
11
|
+
@data_store = [ @yurt_root, "content/" ].join
|
12
|
+
@web_root = [ @yurt_root, "htdocs/" ].join
|
13
|
+
@includes = [ @web_root, "includes/content/" ].join
|
14
|
+
@metatags = ".metatags"
|
15
|
+
@partial = ".partial"
|
16
|
+
@ext = ".html"
|
17
|
+
end
|
18
|
+
|
19
|
+
def merge path, file
|
20
|
+
[ path, '/', file ].join.gsub( /\/\/*/, "/" )
|
21
|
+
end
|
22
|
+
|
23
|
+
def path_to_orig_content path
|
24
|
+
[ @data_store, path ].join
|
25
|
+
end
|
26
|
+
|
27
|
+
def path_to_metatags path
|
28
|
+
[ @includes, path, @metatags, @ext ].join
|
29
|
+
end
|
30
|
+
|
31
|
+
def path_to_content path
|
32
|
+
[ @includes, path, @ext ].join
|
33
|
+
end
|
34
|
+
|
35
|
+
def path_to_placeholder path
|
36
|
+
[ @web_root, path, @ext].join
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_dir_listing path
|
40
|
+
@contents = Hash.new
|
41
|
+
Dir.chdir( path_to_orig_content( path ) ) do
|
42
|
+
Dir.foreach(".") do |entry|
|
43
|
+
@contents[entry] = [ File.ftype(entry) ] unless ( entry =~ /^\./ or entry =~ /~$/ )
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
@contents
|
48
|
+
end
|
49
|
+
|
50
|
+
def sanitize_path path
|
51
|
+
if path == ""
|
52
|
+
"/"
|
53
|
+
else
|
54
|
+
path.gsub!( /^\//, '' )
|
55
|
+
path.gsub!( /\/$/, '' )
|
56
|
+
[ '/', path, '/' ].join.gsub( /\/\/*/,"/" )
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def sanitize_filename f
|
61
|
+
f.gsub!(/^\//, "")
|
62
|
+
f.gsub!(/[^\w\.\-]/, "_")
|
63
|
+
|
64
|
+
f
|
65
|
+
end
|
66
|
+
|
67
|
+
def make_new_dir path, name
|
68
|
+
p = merge( path, sanitize_filename( name ) )
|
69
|
+
|
70
|
+
Dir.mkdir( [ @data_store, p ].join )
|
71
|
+
Dir.mkdir( [ @includes, p ].join )
|
72
|
+
Dir.mkdir( [ @web_root, p ].join )
|
73
|
+
|
74
|
+
File.chmod( 0777, [ @data_store, p ].join )
|
75
|
+
File.chmod( 0777, [ @includes, p ].join )
|
76
|
+
File.chmod( 0777, [ @web_root, p ].join )
|
77
|
+
end
|
78
|
+
|
79
|
+
def make_content_as_yaml input
|
80
|
+
content = Hash.new
|
81
|
+
if input.partial == "y"
|
82
|
+
content[ "partial" ] = input.partial
|
83
|
+
else
|
84
|
+
content[ "title" ] = input.title
|
85
|
+
content[ "description" ] = input.description
|
86
|
+
content[ "keywords" ] = input.keywords
|
87
|
+
content[ "template" ] = input.template
|
88
|
+
end
|
89
|
+
content[ "content" ] = input.content
|
90
|
+
|
91
|
+
content.to_yaml
|
92
|
+
end
|
93
|
+
|
94
|
+
def make_metatags input
|
95
|
+
t = [ '<!--#set var="TITLE" value="', input.title, '" -->', "\n" ].join if input.title =~ /\w/
|
96
|
+
d = [ '<!--#set var="DESCRIPTION" value="', input.description, '" -->', "\n" ].join if input.description =~ /\w/
|
97
|
+
k = [ '<!--#set var="KEYWORDS" value="', input.keywords, '" -->', "\n" ].join if input.keywords =~ /\w/
|
98
|
+
|
99
|
+
[ t, d, k ].join
|
100
|
+
end
|
101
|
+
|
102
|
+
def parse_content c
|
103
|
+
BlueCloth.new(c).to_html
|
104
|
+
end
|
105
|
+
|
106
|
+
def make_placeholder path, template
|
107
|
+
if template == nil or template == ""
|
108
|
+
template = "template.html"
|
109
|
+
end
|
110
|
+
|
111
|
+
[
|
112
|
+
'<!--#set var="PAGE" value="',
|
113
|
+
path,
|
114
|
+
'" -->',
|
115
|
+
"\n",
|
116
|
+
'<!--#include virtual="/includes/',
|
117
|
+
template,
|
118
|
+
'" -->',
|
119
|
+
"\n"
|
120
|
+
].join
|
121
|
+
end
|
122
|
+
|
123
|
+
def delete obj
|
124
|
+
f = path_to_orig_content( obj )
|
125
|
+
|
126
|
+
if File.exists?( f )
|
127
|
+
if File.ftype( f ) == "directory"
|
128
|
+
Dir.delete( f )
|
129
|
+
[ :path_to_content,
|
130
|
+
:path_to_placeholder ].each do |p|
|
131
|
+
f = send( p, obj ).gsub(/\.html/, '')
|
132
|
+
Dir.delete( f )
|
133
|
+
end
|
134
|
+
else
|
135
|
+
File.delete( f )
|
136
|
+
[ :path_to_metatags,
|
137
|
+
:path_to_content,
|
138
|
+
:path_to_placeholder ].each do |p|
|
139
|
+
f = send( p, obj )
|
140
|
+
File.delete( f )
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def get_file_metadata path
|
147
|
+
metadata = YAML.load( File.open( path_to_orig_content( path ) ) )
|
148
|
+
metadata[ "filename" ] = File.basename( path_to_orig_content( path ) )
|
149
|
+
metadata[ "path" ] = File.dirname( path )
|
150
|
+
|
151
|
+
metadata
|
152
|
+
end
|
153
|
+
|
154
|
+
def write_file path, contents
|
155
|
+
f = File.new( path, "w" )
|
156
|
+
f.puts contents
|
157
|
+
f.close
|
158
|
+
begin
|
159
|
+
File.chmod(0776,path)
|
160
|
+
rescue
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def write_all_files input
|
165
|
+
path = merge( input.path, sanitize_filename( input.filename ) )
|
166
|
+
|
167
|
+
write_file( path_to_orig_content( path ), make_content_as_yaml( input ) )
|
168
|
+
write_file( path_to_placeholder( path ), make_placeholder( path, input.template ) )
|
169
|
+
write_file( path_to_content( path ), parse_content( input.content ) )
|
170
|
+
|
171
|
+
if input.partial != "y"
|
172
|
+
write_file( path_to_metatags( path ), make_metatags( input ) )
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/site/content/index
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
title: ""
|
3
|
+
description: ""
|
4
|
+
content: |-
|
5
|
+
# Congratulations! #
|
6
|
+
|
7
|
+
You have successfully completed a Yurt CMS installation! At this point you have a few possible next steps in building your site:
|
8
|
+
|
9
|
+
* Designing a new template to use with this site
|
10
|
+
* Setting up and pouring in the content through the [web interface](/yurt/)
|
11
|
+
* Setting up and pouring in content in your terminal app.
|
12
|
+
|
13
|
+
(Help files to come)
|
14
|
+
keywords: ""
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<h1>Congratulations!</h1>
|
2
|
+
|
3
|
+
<p>You have successfully completed a Yurt CMS installation! At this point you have a few possible next steps in building your site:</p>
|
4
|
+
|
5
|
+
<ul>
|
6
|
+
<li>Designing a new template to use with this site</li>
|
7
|
+
<li>Setting up and pouring in the content through the <a href="/yurt/">web interface</a></li>
|
8
|
+
<li>Setting up and pouring in content in your terminal app.</li>
|
9
|
+
</ul>
|
10
|
+
|
11
|
+
<p>(Help files to come)</p>
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<!--#include virtual="/includes/template.metatags.html" -->
|
2
|
+
<!--#include virtual="/includes/content/${PAGE}.metatags.html" -->
|
3
|
+
|
4
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
5
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
7
|
+
<head>
|
8
|
+
<title><!--#echo var="TITLE" --></title>
|
9
|
+
<meta name="keywords" content="<!--#echo var="KEYWORDS" -->" />
|
10
|
+
<meta name="description" content="<!--#echo var="DESCRIPTION" -->" />
|
11
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
12
|
+
<link rel="stylesheet" type="text/css" href="/media/css/styles.css" />
|
13
|
+
<script type="text/javascript" language="javascript" src="/media/js/prototype.js"></script>
|
14
|
+
</head>
|
15
|
+
<body>
|
16
|
+
<img src="/yurt/media/images/admin_head.jpg" width="481" height="79" border="0" alt="yurt: a content management system" id="header_img" />
|
17
|
+
|
18
|
+
<div id="main">
|
19
|
+
<!--#include virtual="/includes/content/${PAGE}.html" -->
|
20
|
+
</div>
|
21
|
+
</body>
|
22
|
+
</html>
|
@@ -0,0 +1,106 @@
|
|
1
|
+
body {
|
2
|
+
margin: 0;
|
3
|
+
padding: 0;
|
4
|
+
background-color: #eeeeea;
|
5
|
+
background-image: url("/yurt/media/images/admin_bg.gif");
|
6
|
+
background-position: top left;
|
7
|
+
background-repeat: repeat-x;
|
8
|
+
font-size: 100%;
|
9
|
+
}
|
10
|
+
|
11
|
+
#header_img {
|
12
|
+
position: absolute;
|
13
|
+
margin: 0;
|
14
|
+
padding: 0;
|
15
|
+
}
|
16
|
+
|
17
|
+
#menu {
|
18
|
+
padding: 0;
|
19
|
+
position: absolute;
|
20
|
+
margin-left: 50px;
|
21
|
+
margin-top: 100px;
|
22
|
+
width: 220px;
|
23
|
+
font-size: 0.8em;
|
24
|
+
font-family: arial, sans-serif;
|
25
|
+
}
|
26
|
+
|
27
|
+
#menu ul {
|
28
|
+
margin: 0;
|
29
|
+
padding: 0;
|
30
|
+
font-size: 1.0em;
|
31
|
+
margin-bottom: 1.0em;
|
32
|
+
list-style: none;
|
33
|
+
}
|
34
|
+
|
35
|
+
#menu li {
|
36
|
+
margin: 0;
|
37
|
+
margin-bottom: 0.3em;
|
38
|
+
padding: 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
#menu a {
|
42
|
+
text-decoration: none;
|
43
|
+
}
|
44
|
+
|
45
|
+
#menu a:hover {
|
46
|
+
text-decoration: underline;
|
47
|
+
}
|
48
|
+
|
49
|
+
#main {
|
50
|
+
padding: 0;
|
51
|
+
position: absolute;
|
52
|
+
margin-left: 285px;
|
53
|
+
margin-top: 100px;
|
54
|
+
width: 600px;
|
55
|
+
font-size: 1.0em;
|
56
|
+
font-family: optima, arial, sans-serif;
|
57
|
+
line-height: 1.3em;
|
58
|
+
}
|
59
|
+
|
60
|
+
#main h1 {
|
61
|
+
margin: 0;
|
62
|
+
padding: 0;
|
63
|
+
font-size: 1.4em;
|
64
|
+
margin-bottom: 0.3em;
|
65
|
+
}
|
66
|
+
|
67
|
+
#main h2 {
|
68
|
+
margin: 0;
|
69
|
+
padding: 0;
|
70
|
+
font-size: 1.2em;
|
71
|
+
margin-bottom: 0.2em;
|
72
|
+
}
|
73
|
+
|
74
|
+
#main h3 {
|
75
|
+
margin: 0;
|
76
|
+
padding: 0;
|
77
|
+
font-size: 1.1em;
|
78
|
+
margin-bottom: 0.2em;
|
79
|
+
}
|
80
|
+
|
81
|
+
#main h4, #main h5, #main h6 {
|
82
|
+
margin: 0;
|
83
|
+
padding: 0;
|
84
|
+
font-size: 1.0em;
|
85
|
+
}
|
86
|
+
|
87
|
+
#main p {
|
88
|
+
margin: 0;
|
89
|
+
padding: 0;
|
90
|
+
font-size: 1.0em;
|
91
|
+
margin-bottom: 1.0em;
|
92
|
+
text-indent: 2em;
|
93
|
+
}
|
94
|
+
|
95
|
+
#main ul {
|
96
|
+
margin: 0;
|
97
|
+
padding: 0;
|
98
|
+
padding-left: 2em;
|
99
|
+
font-size: 1.0em;
|
100
|
+
margin-bottom: 1.0em;
|
101
|
+
list-style: square;
|
102
|
+
}
|
103
|
+
|
104
|
+
#main li {
|
105
|
+
margin-bottom: 0.3em;
|
106
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|