Advertisement
  1. Code
  2. CMS

Erstellen eines CMS: RubyPress  

Scroll to top
Read Time: 16 min

German (Deutsch) translation by Wilhelm Wolf (you can also view the original English article)

Nach dem erstellen eines content-management-system (CMS) Basis-Struktur, und den eigentlichen server mit Gehen und Node.js Sie sind bereit, zu versuchen, Ihre hand auf eine andere Sprache. 

Dieses mal bin ich mit der Ruby-Sprache, den server zu erstellen. Ich habe festgestellt, dass durch die Schaffung der gleichen-Programm in mehreren Sprachen, Sie beginnen, um neue Erkenntnisse über bessere Möglichkeiten, um die Umsetzung des Programms.  Sie sehen auch mehr Möglichkeiten zum hinzufügen von Funktionalität in das Programm. Lassen Sie uns begonnen erhalten. 

 Setup und Laden der Bibliotheken

 Programmieren in Ruby, müssen Sie die neueste version auf Ihrem system installiert. Viele Betriebssysteme kommen vorinstalliert mit Ruby in diesen Tagen (Linux und OS X), aber Sie haben in der Regel eine ältere version. Dieses tutorial geht davon aus, dass Ruby version 2.4. 

 Der einfachste Weg, um ein upgrade auf die neueste version von ruby ist die Verwendung von RVM. Installieren RVM auf Linux oder Mac OS X, geben Sie den folgenden in einem terminal:

1
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
2
curl -sSL https://get.rvm.io | bash -s stable

 Dies schafft eine sichere Verbindung zu herunterladen und installieren RVM. Dies installiert die neueste stabile Version von Ruby ebenso. Sie haben, um neu zu laden Sie Ihre Schale, um die installation abzuschließen. 

Für Windows können Sie die Windows-Ruby Installer. Derzeit, dieses Paket ist bis zu Ruby 2.2.2, das ist gut zu laufen, die Bibliotheken und Skripte in diesem tutorial. 

Sobald der Ruby-Sprache ist korrekt installiert, Sie können nun installieren Sie die Bibliotheken. Ruby, genau wie Sie Gehen und-Knoten, ein Paket-manager für die Installation von Drittanbieter-Bibliotheken. In dem terminal, geben Sie den folgenden: 

1
gem install sinatra
2
gem install ruby-handlebars
3
gem install kramdown
4
gem install slim

 Dies installiert die Sinatra, Ruby LENKER, Kramdown, Schlank und Bibliotheken. Sinatra ist ein web application framework. Ruby LENKER implementiert die LENKER-Template-engine in Ruby.  Kramdown ist ein Markdown-zu-HTML-Konverter. Slim ist eine Jade-ähnliche Bibliothek, aber es hat nicht Jade makro-Definitionen. Also, die Makros verwendet, in der News-und Blog-post-Indizes sind jetzt normale Jade.

 Erstellen der rubyPress.rb-Datei

 Im obersten Verzeichnis, erstellen Sie die Datei rubyPress.rb und fügen Sie den folgenden code. Ich werde zu jedem Abschnitt, wie es der Datei Hinzugefügt.

1
#

2
# Load the Libraries.

3
#

4
require 'sinatra'  		# https://www.sinatrarb.com/

5
require 'ruby-handlebars' 	# https://github.com/vincent-psarga/ruby-handlebars

6
require 'kramdown' 			# http://kramdown.gettalong.org

7
require 'slim' 				# http://slim-lang.com/

8
require 'json'
9
require 'date'

 Das erste, was zu tun ist, laden Sie die Bibliotheken. Im Gegensatz zu mit Node.js diese sind nicht geladen, in eine variable. Ruby Bibliotheken Ihre Funktionen zum Programm-Umfang.

1
#

2
# Setup the Handlebars engine.

3
#

4
$hbs = Handlebars::Handlebars.new
5
6
#

7
# HandleBars Helper:   date

8
#

9
# Description:         This helper returns the current date

10
#                      based on the format given.

11
#

12
$hbs.register_helper('date') {|context, format|
13
	now = Date.today
14
	now.strftime(format)
15
}
16
17
#

18
# HandleBars Helper:   cdate

19
#

20
# Description:         This helper returns the given date

21
#                      based on the format given.

22
#

23
$hbs.register_helper('cdate') {|context, date, format|
24
	day = Date.parse(date)
25
	day.strftime(format)
26
}
27
28
#

29
# HandleBars Helper:   save

30
#

31
# Description:         This helper expects a

32
#                      "|" where the name

33
#                      is saved with the value for future

34
#                      expansions. It also returns the

35
#                      value directly.

36
#

37
$hbs.register_helper('save') {|context, name, text|
38
	#

39
	# If the text parameter isn't there, then it is the 

40
	# goPress format all combined into the name. Split it 

41
	# out. The parameters are not String objects. 

42
	# Therefore, they need converted first.

43
	#

44
	name = String.try_convert(name)
45
	if name.count("|") > 0
46
		parts = name.split('|')
47
		name = parts[0]
48
		text = parts[1]
49
	end
50
51
	#

52
	# Register the new helper.

53
	#

54
	$hbs.register_helper(name) {|context, value|
55
		text
56
	}
57
58
	#

59
	# Return the text.

60
	#

61
	text
62
}

Die LENKER-Bibliothek wird initialisiert mit den verschiedenen Hilfsfunktionen definiert. Die Hilfsfunktionen definiert sind date, cdate, und speichern. 

 Das Datum helper-Funktion das aktuelle Datum und die Uhrzeit und formatiert Sie entsprechend dem format-string, der an die Helfer. cdate ist ähnlich, außer für die übergabe des Datums zuerst.  Die save-helper können Sie angeben, einen Namen und einen Wert. Es schafft einen neuen Helfer mit dem Namen name aus und übergibt wieder den Wert.  Dadurch können Sie Variablen erstellen, werden einmal angegeben und auf viele Standorte. Diese Funktion nimmt auch die Go-version, die erwartet einen string mit dem Namen, '|' als Trennzeichen, und Wert. 

1
#

2
# Load Server Data.

3
#

4
$parts = {}
5
$parts = JSON.parse(File.read './server.json')
6
$styleDir = Dir.getwd + '/themes/styling/' + $parts['CurrentStyling']
7
$layoutDir = Dir.getwd + '/themes/layouts/' + $parts['CurrentLayout']
8
9
#

10
# Load the layouts and styles defaults.

11
#

12
$parts["layout"] = File.read $layoutDir + '/template.html'
13
$parts["404"] = File.read $styleDir + '/404.html'
14
$parts["footer"] = File.read $styleDir + '/footer.html'
15
$parts["header"] = File.read $styleDir + '/header.html'
16
$parts["sidebar"] = File.read $styleDir + '/sidebar.html'
17
18
#

19
# Load all the page parts in the parts directory.

20
#

21
Dir.entries($parts["Sitebase"] + '/parts/').select {|f|
22
	if !File.directory? f
23
		$parts[File.basename(f, ".*")] = File.read $parts["Sitebase"] + '/parts/' + f
24
	end
25
}
26
27
#

28
# Setup server defaults:

29
#

30
port = $parts["ServerAddress"].split(":")[2]
31
set :port, port

Der nächste Teil von dem code für das laden der cacheable Elemente der web-site. Dies ist alles im Stile und layout für Ihr Thema, und die Elemente, die in den teilen sub-directory.  Eine Globale variable, $Teile ist, wird zuerst vom server geladen.json-Datei. Diese Informationen werden dann verwendet, um laden Sie die richtigen Elemente für das layout und Thema angegeben. Der LENKER template-engine verwendet diese Informationen zum ausfüllen der Vorlagen. 

1
#

2
# Define the routes for the CMS.

3
#

4
get '/' do
5
  page "main"
6
end
7
8
get '/favicon.ico', :provides => 'ico' do
9
	File.read "#{$parts['Sitebase']}/images/favicon.ico"
10
end
11
12
get '/stylesheets.css', :provides => 'css'  do
13
	File.read "#{$parts["Sitebase"]}/css/final/final.css"
14
end
15
16
get '/scripts.js', :provides => 'js'  do
17
	File.read "#{$parts["Sitebase"]}/js/final/final.js"
18
end
19
20
get '/images/:image', :provides => 'image' do
21
	File.read "#{$parts['Sitebase']}/images/#{parms['image']}"
22
end
23
24
get '/posts/blogs/:blog' do
25
	post 'blogs', params['blog'], 'index'
26
end
27
28
get '/posts/blogs/:blog/:post' do
29
	post 'blogs', params['blog'], params['post']
30
end
31
32
get '/posts/news/:news' do
33
	post 'news', params['news'], 'index'
34
end
35
36
get '/posts/news/:news/:post' do
37
	post 'news', params['news'], params['post']
38
end
39
40
get '/:page' do
41
	page params['page']
42
end

 Der nächste Abschnitt enthält die Definitionen für alle Routen. Sinatra ist eine vollständige REST-konforme server. Aber für das CMS, ich werde nur das get-verb.  Jede route führt die Elemente aus die route zum pass, um die Funktionen für die Herstellung der richtigen Seite. Im Sinatra, ein name mit einem vorangestellten Doppelpunkt gibt einen Abschnitt der route zu passieren, um die route-handler. Diese Elemente sind in einem params-hash-Tabelle.

1
#

2
# Various functions used in the making of the server:

3
#

4
5
#

6
# Function:    page

7
#

8
# Description: This function is for processing a page

9
#              in the CMS.

10
#

11
# Inputs:

12
# 				pg 	The page name to lookup

13
#

14
def page(pg)
15
	processPage $parts["layout"], "#{$parts["Sitebase"]}/pages/#{pg}"
16
end

 Die Seite, die Funktion erhält den Namen einer Seite, von der route und übergibt das layout in der $parts-variable zusammen mit den vollständigen Pfad zu der Seite, die Datei wird benötigt für die Funktion processPage.  Die processPage Funktion nimmt diese Informationen und erstellt die richtige Seite, die es dann gibt. In Ruby, der Ausgang der letzten Funktion ist der Rückgabewert für die Funktion.

1
#

2
# Function:    post

3
#

4
# Description: This function is for processing a post type

5
#              page in the CMS. All blog and news pages are

6
#    				post type pages.

7
#

8
# Inputs:

9
#              type   The type of the post

10
#              cat    The category of the post (blog, news)

11
#              post   The actual page of the post

12
#

13
def post(type, cat, post)
14
	processPage $parts["layout"], "#{$parts["Sitebase"]}/posts/#{type}/#{cat}/#{post}"
15
end

 Die post-Funktion ist ebenso wie die-Seite-Funktion, außer, dass es funktioniert für alle post-Typ-Seiten. Diese Funktion erwartet, dass die post-Typ, post-Kategorie, und die post selbst. Diese erstellen die Adresse für die richtige Seite angezeigt wird.

1
#

2
# Function:    figurePage

3
#

4
# Description: This function is to figure out the page

5
#              type (ie: markdown, HTML, jade, etc), read

6
#              the contents, and translate it to HTML.

7
#

8
# Inputs:

9
#              page      The address of the page 

10
#                        without its extension.

11
#

12
def figurePage(page)
13
	result = ""
14
15
	if File.exist? page + ".html"
16
		#

17
		# It's an HTML file.

18
		#

19
		result = File.read page + ".html"
20
	elsif File.exist? page + ".md"
21
		#

22
		# It's a markdown file.

23
		#

24
		result = Kramdown::Document.new(File.read page + ".md").to_html
25
26
		#

27
		# Fix the fancy quotes from Kramdown. It kills

28
		# the Handlebars parser.

29
		#

30
		result.gsub!("“","\"")
31
		result.gsub!("”","\"")
32
	elsif File.exist? page + ".amber"
33
		#

34
		# It's a jade file. Slim doesn't support

35
		# macros. Therefore, not as powerful as straight jade.

36
		# Also, we have to render any Handlebars first

37
		# since the Slim engine dies on them.

38
		#

39
		File.write("./tmp.txt",$hbs.compile(File.read page + ".amber").call($parts))
40
		result = Slim::Template.new("./tmp.txt").render()
41
	else
42
		#

43
		# Doesn't exist. Give the 404 page.

44
		#

45
		result = $parts["404"]
46
	end
47
48
	#

49
	# Return the results.

50
	#

51
	return result
52
end

 Die figurePage-Funktion verwendet die processPage-Funktion zum Lesen der Inhalte auf der Seite aus dem Datei-system. Diese Funktion erhält den vollständigen Pfad zu der Datei ohne die Erweiterung. figurePage dann tests für eine Datei mit dem angegebenen Namen mit der html-Erweiterung für das Lesen einer HTML-Datei. Die zweite Wahl ist, für eine md-Erweiterung für eine Markdown-Datei. 

 Schließlich prüft es, für ein amber-Erweiterung für Jade-Datei. Denken Sie daran: Amber ist der name der Bibliothek für die Verarbeitung von Jade syntax-Dateien in Go.  Ich hielt es gleich für inter-Funktionalität. Eine HTML-Datei ist einfach wieder vergangen, während alle Markdown-und Jade-Dateien in HTML umgewandelt, bevor die übergabe zurück.

 Wenn eine Datei nicht gefunden, erhält der Benutzer die 404-Seite. Auf diese Weise werden Ihre "Seite nicht gefunden" - Seite sieht genauso aus wie alle anderen Seiten mit Ausnahme der Inhalte.

1
#

2
# Function:    processPage

3
#

4
# Description: The function processes a page by getting

5
#              its contents, combining with all the page

6
#              parts using Handlebars, and processing the

7
#              shortcodes.

8
#

9
# Inputs:

10
#              layout  The layout structure for the page

11
#              page    The complete path to the desired

12
#                      page without its extension.

13
#

14
def processPage(layout, page)
15
	#

16
	# Get the page contents and name.

17
	#

18
	$parts["content"] = figurePage page
19
	$parts["PageName"] = File.basename page
20
21
	#

22
	# Run the page through Handlebars engine.

23
	#

24
	begin
25
		pageHB = $hbs.compile(layout).call($parts)
26
	rescue
27
		pageHB = "

28
Render Error

29


30
"
31
	end
32
33
	#

34
	# Run the page through the shortcodes processor.

35
	#

36
	pageSH = processShortCodes pageHB
37
38
	#

39
	# Run the page through the Handlebar engine again.

40
	#

41
	begin
42
		pageFinal = $hbs.compile(pageSH).call($parts)
43
	rescue
44
		pageFinal = "

45
Render Error

46


47
" + pageSH
48
	end
49
50
	#

51
	# Return the results.

52
	#

53
	return pageFinal
54
end

 Die processPage Funktion führt alle template-Erweiterungen auf der Seite Daten. Es beginnt mit dem Aufruf der figurePage-Funktion, um die Seite Inhalte. Dann verarbeitet es das layout übergeben, um es mit LENKER, erweitern Sie die Vorlage.

Dann die processShortCode Funktion finden und verarbeiten alle shortcodes in die Seite. Die Ergebnisse werden dann an LENKER ein zweites mal zu verarbeiten, keine Makros, Links durch die Kurzwahlnummern. Der Benutzer erhält die endgültigen Ergebnisse. 

1
#

2
# Function:    processShortCodes

3
#

4
# Description: This function takes the page and processes

5
#              all of the shortcodes in the page.

6
#

7
# Inputs:

8
#              page     The contents of the page to 

9
#                       process.

10
#

11
def processShortCodes(page)
12
	#

13
	# Initialize the result variable for returning.

14
	#

15
	result = ""
16
17
	#

18
	# Find the first shortcode

19
	#

20
	scregFind = /\-\[([^\]]*)\]\-/
21
	match1 = scregFind.match(page)
22
	if match1 != nil
23
		#

24
		# We found one! get the text before it

25
		# into the result variable and initialize

26
		# the name, param, and contents variables.

27
		#

28
		name = ""
29
		param = ""
30
		contents = ""
31
		nameLine = match1[1]
32
		loc1 = scregFind =~ page
33
		result = page[0, loc1]
34
35
		#

36
		# Separate out the nameLine into a shortcode

37
		# name and parameters.

38
		#

39
		match2 = /(\w+)(.*)*/.match(nameLine)
40
		if match2.length == 2
41
			#

42
			# Just a name was found.

43
			#

44
			name = match2[1]
45
		else
46
			#

47
			# A name and parameter were found.

48
			#

49
			name = match2[1]
50
			param = match2[2]
51
		end
52
53
		#

54
		# Find the closing shortcode

55
		#

56
		rest = page[loc1+match1[0].length, page.length]
57
		regEnd = Regexp.new("\\-\\[\\/#{name}\\]\\-")
58
		match3 = regEnd.match(rest)
59
		if match3 != nil
60
			#

61
			# Get the contents the tags enclose.

62
			#

63
			loc2 = regEnd =~ rest
64
			contents = rest[0, loc2]
65
66
			#

67
			# Search the contents for shortcodes.

68
			#

69
			contents = processShortCodes(contents)
70
71
			#

72
			# If the shortcode exists, run it and include

73
			# the results. Otherwise, add the contents to

74
			# the result.

75
			#

76
			if $shortcodes.include?(name)
77
				result += $shortcodes[name].call(param, contents)
78
			else
79
				result += contents
80
			end
81
82
			#

83
			# process the shortcodes in the rest of the

84
			# page.

85
			#

86
			rest = rest[loc2 + match3[0].length, page.length]
87
			result += processShortCodes(rest)
88
		else
89
			#

90
			# There wasn't a closure. Therefore, just 

91
			# send the page back.

92
			#

93
			result = page
94
		end
95
	else
96
		#

97
		# No shortcodes. Just return the page.

98
		#

99
		result = page
100
	end
101
102
	return result
103
end

Die processShortCodes Funktion nimmt den text gegeben, findet jeder shortcode, und führt die angegebene Kurzwahlnummer mit den Argumenten und Inhalt der Kurzwahlnummer. Ich nutze den shortcode routine zum verarbeiten der Inhalte für die Kurzwahlnummern sowie.  

Ein shortcode ist eine HTML-ähnliche Tags verwendet -[ und ] -, um die öffnung tag-und -[/ und ]- die schließenden Tags. Das öffnende tag enthält die Parameter für den shortcode auch. Also, ein Beispiel shortcode wäre: 

1
-[box]-
2
This is inside a box.
3
-[/box]-

Dieser shortcode definiert die box shortcode ohne Parameter mit dem Inhalt von Dies ist in einem Karton..   Die box shortcode umschließt den Inhalt in die entsprechenden HTML zu produzieren, ein Feld um den text mit der text zentriert in der box.  Wenn Sie später ändern möchten, wie das Feld gerendert wird, müssen Sie nur ändern Sie die definition der shortcode. Das spart eine Menge Arbeit.

1
#

2
# Data Structure:  $shortcodes

3
#

4
# Description:     This data structure contains all

5
#                  the valid shortcodes names and the

6
#                  function. All shortcodes should

7
#                  receive the arguments and the

8
#                  that the shortcode encompasses.

9
#

10
$shortcodes = {
11
	"box" => lambda { |args, contents|
12
		return("#{contents}")
13
	},
14
   'Column1'=> lambda { |args, contents|
15
		return("#{contents}")
16
   },
17
   'Column2' => lambda { |args, contents|
18
      return("#{contents}")
19
   },
20
   'Column1of3' => lambda { |args, contents|
21
      return("#{contents}")
22
   },
23
   'Column2of3' => lambda { |args, contents|
24
      return("#{contents}")
25
   },
26
   'Column3of3' => lambda { |args, contents|
27
      return("#{contents}")
28
   },
29
   'php' => lambda { |args, contents|
30
      return("#{contents}") }, 'js' => lambda { |args, contents| return("#{contents}") }, "html" => lambda { |args, contents| return("#{contents}") }, 'css' => lambda {|args, contents| return("#{contents}") } }

 Das Letzte, was in der Datei ist die $Kurzwahlnummern hash-Tabelle mit der shortcode-Routinen. Dies sind einfache shortcodes, aber Sie können erstellen Sie weitere Kurzwahlnummern zu sein, so Komplex wie Sie möchten.

 Alle Kurzwahlnummern haben zu akzeptieren zwei Parameter: Argumente und Inhalte. Diese strings enthalten die Parameter, die Kurzwahlnummer und die Inhalte der Kurzwahlnummern umgeben. Da die Kurzwahlnummern sind innerhalb einer hash-Tabelle habe ich eine lambda-Funktion zu definieren. Eine lambda-Funktion ist eine Funktion ohne Namen. Der einzige Weg, um diese Funktionen auszuführen ist, aus dem hash-array.   

Läuft der Server 

Sobald Sie erstellt haben, die rubyPress.rb-Datei mit dem obigen Inhalt, Sie können führen Sie den server mit:  

1
ruby rubyPress.rb

Da das Sinatra-framework arbeitet mit dem Ruby on Rails-Rack-Struktur, die Sie verwenden können, Pow den server zu starten.  Pow richten Sie Ihre system-host-Dateien für den Betrieb Ihrer server lokal die gleiche, wie es wäre, von einer gehosteten Website. Sie installieren können, mit Pow-Pulver mit den folgenden Befehlen in der Kommandozeile: 

1
gem install powder
2
powder install

 Pulver ist ein command-line-routine für die Verwaltung von Pow-sites auf Ihrem computer. Um Pow zu sehen, Ihre Website, müssen Sie einen soft-link zu Ihrem Projekt-Verzeichnis in die ~/.pow-Verzeichnis.  Wenn der server in /Users/test/Documents/rubyPress-Verzeichnis, führen Sie die folgenden Befehle ein:

1
cd ~/.pow
2
ln -s /Users/test/Documents/rubyPress rubyPress

 Ln -s erstellt einen soft-link auf das angegebene Verzeichnis erste, die mit dem angegebenen Namen zweitens. Pow wird dann eingerichtet, eine domain auf Ihrem system mit dem Namen des soft-link.  In dem obigen Beispiel, gehen Sie zu der web-site http://rubyPress.dev im browser lädt die Seite aus dem server.

 Um den server zu starten, geben Sie den folgenden nach der Erstellung die soft-link:

1
powder start

 Das nachladen der server nach einigen änderungen im code, geben Sie den folgenden:

1
powder restart
rubyPress Main PagerubyPress Main PagerubyPress Main Page
rubyPress Hauptseite 

Werde die website im browser wird das Ergebnis im Bild oben. Pow wird die Einrichtung der Website an http://rubyPress.dev. Egal welche Methode Sie verwenden, um den Start der Website, Sie werden sehen, die gleichen sich Seite. 

 Fazit

Gut, Sie haben es getan. Einem anderen CMS, aber dieses mal in Ruby. Diese version ist die kürzeste version der CMS erstellt in dieser Serie. Experimentieren Sie mit dem code und sehen Sie, wie Sie erweitern dieses Basis-framework. 

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.