geb 0.1.11
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.
- checksums.yaml +7 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +37 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE +21 -0
- data/README.md +384 -0
- data/Rakefile +21 -0
- data/bin/geb +21 -0
- data/lib/geb/cli.rb +40 -0
- data/lib/geb/commands/build.rb +59 -0
- data/lib/geb/commands/init.rb +70 -0
- data/lib/geb/commands/release.rb +54 -0
- data/lib/geb/commands/remote.rb +48 -0
- data/lib/geb/commands/server.rb +77 -0
- data/lib/geb/commands/upload.rb +48 -0
- data/lib/geb/commands/version.rb +36 -0
- data/lib/geb/config.rb +103 -0
- data/lib/geb/defaults.rb +44 -0
- data/lib/geb/git.rb +112 -0
- data/lib/geb/page.rb +217 -0
- data/lib/geb/partial.rb +150 -0
- data/lib/geb/samples/basic/assets/css/site.css +7 -0
- data/lib/geb/samples/basic/assets/images/android-chrome-192x192.png +0 -0
- data/lib/geb/samples/basic/assets/images/android-chrome-512x512.png +0 -0
- data/lib/geb/samples/basic/assets/images/apple-touch-icon.png +0 -0
- data/lib/geb/samples/basic/assets/images/favicon-16x16.png +0 -0
- data/lib/geb/samples/basic/assets/images/favicon-32x32.png +0 -0
- data/lib/geb/samples/basic/assets/images/favicon.ico +0 -0
- data/lib/geb/samples/basic/assets/images/hero.png +0 -0
- data/lib/geb/samples/basic/assets/images/og-thumb.png +0 -0
- data/lib/geb/samples/basic/assets/images/twitter-thumb.png +0 -0
- data/lib/geb/samples/basic/assets/js/site.js +5 -0
- data/lib/geb/samples/basic/geb.config.yml +70 -0
- data/lib/geb/samples/basic/index.html +11 -0
- data/lib/geb/samples/basic/page.html +11 -0
- data/lib/geb/samples/basic/shared/partials/_analytics.html +9 -0
- data/lib/geb/samples/basic/shared/partials/_footer.html +3 -0
- data/lib/geb/samples/basic/shared/partials/_global_assets.html +19 -0
- data/lib/geb/samples/basic/shared/partials/_header.html +0 -0
- data/lib/geb/samples/basic/shared/partials/_meta_tags.html +34 -0
- data/lib/geb/samples/basic/shared/templates/_blog_post.html +0 -0
- data/lib/geb/samples/basic/shared/templates/_site.html +19 -0
- data/lib/geb/samples/basic/site.webmanifest +1 -0
- data/lib/geb/samples/bootstrap_jquery/assets/css/site.css +7 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/android-chrome-192x192.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/android-chrome-512x512.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/apple-touch-icon.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/favicon-16x16.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/favicon-32x32.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/favicon.ico +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/hero.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/og-thumb.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/twitter-thumb.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/js/site.js +5 -0
- data/lib/geb/samples/bootstrap_jquery/blog/blog_post_1.html +35 -0
- data/lib/geb/samples/bootstrap_jquery/blog/blog_post_2.html +35 -0
- data/lib/geb/samples/bootstrap_jquery/blog/blog_post_3.html +35 -0
- data/lib/geb/samples/bootstrap_jquery/blog/index.html +17 -0
- data/lib/geb/samples/bootstrap_jquery/geb.config.yml +69 -0
- data/lib/geb/samples/bootstrap_jquery/index.html +11 -0
- data/lib/geb/samples/bootstrap_jquery/page.html +11 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_analytics.html +9 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_footer.html +3 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_global_assets.html +19 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_header.html +0 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_meta_tags.html +34 -0
- data/lib/geb/samples/bootstrap_jquery/shared/templates/_blog_post.html +0 -0
- data/lib/geb/samples/bootstrap_jquery/shared/templates/_site.html +19 -0
- data/lib/geb/samples/bootstrap_jquery/site.webmanifest +1 -0
- data/lib/geb/samples/geb.config.yml +70 -0
- data/lib/geb/server.rb +138 -0
- data/lib/geb/site/build.rb +189 -0
- data/lib/geb/site/core.rb +229 -0
- data/lib/geb/site/release.rb +70 -0
- data/lib/geb/site/remote.rb +142 -0
- data/lib/geb/site/template.rb +208 -0
- data/lib/geb/site.rb +83 -0
- data/lib/geb/template.rb +166 -0
- data/lib/geb/utilities.rb +110 -0
- data/lib/geb.rb +36 -0
- data/lib/seth.rb +50 -0
- data/sig/geb.rbs +4 -0
- data/test/api tests/test_cli.rb +200 -0
- data/test/api tests/test_config.rb +330 -0
- data/test/api tests/test_defaults.rb +62 -0
- data/test/api tests/test_git.rb +105 -0
- data/test/api tests/test_page.rb +320 -0
- data/test/api tests/test_partial.rb +152 -0
- data/test/api tests/test_server.rb +416 -0
- data/test/api tests/test_site.rb +1315 -0
- data/test/api tests/test_template.rb +249 -0
- data/test/api tests/test_utilities.rb +162 -0
- data/test/command tests/test_geb_build.rb +199 -0
- data/test/command tests/test_geb_init.rb +312 -0
- data/test/command tests/test_geb_release.rb +166 -0
- data/test/command tests/test_geb_remote.rb +66 -0
- data/test/command tests/test_geb_server.rb +122 -0
- data/test/command tests/test_geb_upload.rb +96 -0
- data/test/command tests/test_geb_version.rb +58 -0
- data/test/support/geb_api_test.rb +37 -0
- data/test/support/geb_cli_test.rb +275 -0
- data/test/support/geb_minitest_ext.rb +35 -0
- data/test/support/geb_test_helpers.rb +84 -0
- data/test/support/geb_web_server_proxy.rb +128 -0
- data/test/test_helper.rb +61 -0
- metadata +301 -0
data/lib/geb/page.rb
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# Represents a site object, handles creation of new sites and site templates
|
|
4
|
+
# Templates can be one of the following:
|
|
5
|
+
# - name of the site template that comes bundled with geb
|
|
6
|
+
# - a local directory that is a valid site template
|
|
7
|
+
# - a URL to a geb site template packaged as a zip file
|
|
8
|
+
#
|
|
9
|
+
# @title Geb - Page
|
|
10
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
|
11
|
+
# @copyright 2024 Edin Mustajbegovic
|
|
12
|
+
# @license MIT
|
|
13
|
+
#
|
|
14
|
+
# @todo Make insert pattern configurable
|
|
15
|
+
#
|
|
16
|
+
# @see https://github.com/mainfram-work/geb for more information
|
|
17
|
+
|
|
18
|
+
# include the required libraries
|
|
19
|
+
require 'fileutils'
|
|
20
|
+
|
|
21
|
+
module Geb
|
|
22
|
+
class Page
|
|
23
|
+
|
|
24
|
+
# insert pattern constant
|
|
25
|
+
INSERT_PATTERN = /<%= insert: (.*?) %>/
|
|
26
|
+
|
|
27
|
+
class PageFileNotFound < Geb::Error
|
|
28
|
+
MESSAGE = "Page file not found".freeze
|
|
29
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
|
30
|
+
end # class PageFileNotFound < Geb::Error
|
|
31
|
+
|
|
32
|
+
class PageFileReadFailure < Geb::Error
|
|
33
|
+
MESSAGE = "Failed to read the page file.".freeze
|
|
34
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
|
35
|
+
end # class PageFileReadFailure < Geb::Error
|
|
36
|
+
|
|
37
|
+
class PageMissingTemplateDefition < Geb::Error
|
|
38
|
+
MESSAGE = "Page is missing template defitions but has insert sections defined".freeze
|
|
39
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
|
40
|
+
end # class PageMissingTemplateDefition < Geb::Error
|
|
41
|
+
|
|
42
|
+
class FailedToOutputPage < Geb::Error
|
|
43
|
+
MESSAGE = "Failed to create output page".freeze
|
|
44
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
|
45
|
+
end # class FailedToOutputPage < Geb::Error
|
|
46
|
+
|
|
47
|
+
# @!attribute [r] site
|
|
48
|
+
# @return [Geb::Site] the site object
|
|
49
|
+
attr_reader :site
|
|
50
|
+
|
|
51
|
+
# @!attribute [r] path
|
|
52
|
+
# @return [String] the page path
|
|
53
|
+
attr_reader :path
|
|
54
|
+
|
|
55
|
+
# @!attribute [r] content
|
|
56
|
+
# @return [String] the page content
|
|
57
|
+
attr_reader :content
|
|
58
|
+
|
|
59
|
+
# @!attribute [r] parsed_content
|
|
60
|
+
# @return [String] the parsed page content
|
|
61
|
+
attr_reader :parsed_content
|
|
62
|
+
|
|
63
|
+
# page constructor, initializes the page object and attributes
|
|
64
|
+
# @param site [Geb::Site] the site object
|
|
65
|
+
# @param path [String] the page path
|
|
66
|
+
# @raise [PageFileNotFound] if the page file does not exist
|
|
67
|
+
# @raise [PageFileReadFailure] if the page file could not be read
|
|
68
|
+
# @return [Geb::Page] the page object
|
|
69
|
+
def initialize(site, path)
|
|
70
|
+
|
|
71
|
+
# set the site and path
|
|
72
|
+
@site = site
|
|
73
|
+
@path = path
|
|
74
|
+
|
|
75
|
+
# check if the page file exists
|
|
76
|
+
raise PageFileNotFound.new(@path) unless page_file_exists?
|
|
77
|
+
|
|
78
|
+
Geb.log ""
|
|
79
|
+
Geb.log " - loading page: #{page_name}"
|
|
80
|
+
|
|
81
|
+
# read the page file, raise an error if the file could not be read
|
|
82
|
+
begin
|
|
83
|
+
@content = File.read(@path)
|
|
84
|
+
rescue => e
|
|
85
|
+
raise PageFileReadFailure.new(e.message)
|
|
86
|
+
end # begin
|
|
87
|
+
|
|
88
|
+
# parse the page content
|
|
89
|
+
parse()
|
|
90
|
+
|
|
91
|
+
end # def initialize
|
|
92
|
+
|
|
93
|
+
# parse the page content for templates and partials
|
|
94
|
+
def parse
|
|
95
|
+
|
|
96
|
+
# initalise the new page content
|
|
97
|
+
@parsed_content = @content.dup
|
|
98
|
+
|
|
99
|
+
# parse the content for templates and partials
|
|
100
|
+
@parsed_content = parse_for_templates(@parsed_content)
|
|
101
|
+
@parsed_content = parse_for_partials(@parsed_content)
|
|
102
|
+
|
|
103
|
+
end # def parse
|
|
104
|
+
|
|
105
|
+
# parse the content for templates. This method will keep looking for templates until all templates are found as
|
|
106
|
+
# templates can be based on templates.
|
|
107
|
+
# @param content [String] the content to parse for templates. Default is the parsed page content.
|
|
108
|
+
# @return [String] the parsed content, with no templates to parse.
|
|
109
|
+
# @raise [PageMissingTemplateDefition] if a template sections are found but the template declaration is not.
|
|
110
|
+
def parse_for_templates(content = @parsed_content)
|
|
111
|
+
|
|
112
|
+
# initialise a flag to keep looking for templates
|
|
113
|
+
keep_looking_for_template = true
|
|
114
|
+
|
|
115
|
+
# keep looking for template until we find them all
|
|
116
|
+
while keep_looking_for_template
|
|
117
|
+
|
|
118
|
+
# attempt to extract the template path and sections
|
|
119
|
+
template_path = Geb::Template.extract_template_path(content)
|
|
120
|
+
template_sections = Geb::Template.extract_sections_for_template(content)
|
|
121
|
+
|
|
122
|
+
# raise an error if template sections are defined but the template is not
|
|
123
|
+
raise PageMissingTemplateDefition.new(page_name) if template_sections.any? && template_path.nil?
|
|
124
|
+
|
|
125
|
+
# check if we found a template
|
|
126
|
+
if template_path.nil?
|
|
127
|
+
|
|
128
|
+
# we did not find a template, so we are done
|
|
129
|
+
keep_looking_for_template = false
|
|
130
|
+
|
|
131
|
+
else
|
|
132
|
+
|
|
133
|
+
# create a new template object
|
|
134
|
+
template = Geb::Template.load(File.join(@site.site_path, template_path))
|
|
135
|
+
|
|
136
|
+
# parse the template content and replace the insert sections
|
|
137
|
+
content = template.parse(template_sections)
|
|
138
|
+
|
|
139
|
+
end # unless template_path.nil?
|
|
140
|
+
|
|
141
|
+
end # while keep_looking_for_template
|
|
142
|
+
|
|
143
|
+
# return the parsed content with templates handled
|
|
144
|
+
return content
|
|
145
|
+
|
|
146
|
+
end # def parse_for_templates
|
|
147
|
+
|
|
148
|
+
# parse the content for partials. This method will keep looking for partials until all partials are found as
|
|
149
|
+
# partials can be embeded in other partials.
|
|
150
|
+
# @param content [String] the content to parse for partials. Default is the parsed page content.
|
|
151
|
+
# @return [String] the parsed content, with no partials to parse.
|
|
152
|
+
def parse_for_partials(content = @parsed_content)
|
|
153
|
+
|
|
154
|
+
# initialise a flag to keep looking for partials
|
|
155
|
+
keep_looking_for_partials = true
|
|
156
|
+
|
|
157
|
+
# keep looking for partials until we find them all (partials can be embeded in other partials)
|
|
158
|
+
while keep_looking_for_partials
|
|
159
|
+
|
|
160
|
+
# attempt to extract the partial paths
|
|
161
|
+
found_partials, content = Geb::Partial.process_partials(@site.site_path, content)
|
|
162
|
+
|
|
163
|
+
# check if we found any partials, if not we are done
|
|
164
|
+
keep_looking_for_partials = (found_partials != 0)
|
|
165
|
+
|
|
166
|
+
end # while keep_looking_for_partials
|
|
167
|
+
|
|
168
|
+
# return the parsed content with partials handled
|
|
169
|
+
return content
|
|
170
|
+
|
|
171
|
+
end # def parse_for_partials
|
|
172
|
+
|
|
173
|
+
# build the page, save it to the output folder
|
|
174
|
+
# @param output_path [String] the output path
|
|
175
|
+
# @raise [FailedToOutputPage] if the page could not be saved to the output folder
|
|
176
|
+
def build(output_path)
|
|
177
|
+
|
|
178
|
+
# build the page
|
|
179
|
+
Geb.log " - building page: #{page_name}"
|
|
180
|
+
|
|
181
|
+
# strip whitespace (spaces and newlines) at the beginning and at the end of the file
|
|
182
|
+
@parsed_content = @parsed_content.strip
|
|
183
|
+
|
|
184
|
+
# build the output filename
|
|
185
|
+
output_filename = @path.gsub(@site.site_path, output_path)
|
|
186
|
+
|
|
187
|
+
# attempt to create the output directory and file
|
|
188
|
+
begin
|
|
189
|
+
|
|
190
|
+
# make sure the output directory for the file exists
|
|
191
|
+
FileUtils.mkdir_p(File.dirname(output_filename))
|
|
192
|
+
|
|
193
|
+
# write the content to the output file
|
|
194
|
+
File.write(output_filename, @parsed_content)
|
|
195
|
+
|
|
196
|
+
rescue => e
|
|
197
|
+
raise FailedToOutputPage.new(e.message)
|
|
198
|
+
end # begin rescue
|
|
199
|
+
|
|
200
|
+
end # def build
|
|
201
|
+
|
|
202
|
+
private
|
|
203
|
+
|
|
204
|
+
# get the page name by removing the site folder from the path
|
|
205
|
+
# @return [String]
|
|
206
|
+
def page_name
|
|
207
|
+
return @path.gsub(@site.site_path, '')
|
|
208
|
+
end # def page_name
|
|
209
|
+
|
|
210
|
+
# check if the page file exists, returns true if the file exists, false otherwise
|
|
211
|
+
# @return [Boolean]
|
|
212
|
+
def page_file_exists?
|
|
213
|
+
return File.exist?(@path)
|
|
214
|
+
end # def page_file_exists?
|
|
215
|
+
|
|
216
|
+
end # class Page
|
|
217
|
+
end # module Geb
|
data/lib/geb/partial.rb
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# Represents a page partial. A page partial is a file that contains
|
|
4
|
+
# content that is to be inserted in the page at the pace where the partial was
|
|
5
|
+
# declared. The class keeps a cache of already loaded partials.
|
|
6
|
+
#
|
|
7
|
+
# @title Geb - Partial
|
|
8
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
|
9
|
+
# @copyright 2024 Edin Mustajbegovic
|
|
10
|
+
# @license MIT
|
|
11
|
+
#
|
|
12
|
+
# @todo Make partial pattern configurable
|
|
13
|
+
#
|
|
14
|
+
# @see https://github.com/mainfram-work/geb for more information
|
|
15
|
+
|
|
16
|
+
# include the required libraries
|
|
17
|
+
require 'fileutils'
|
|
18
|
+
|
|
19
|
+
module Geb
|
|
20
|
+
class Partial
|
|
21
|
+
|
|
22
|
+
# partial pattern constant
|
|
23
|
+
PARTIAL_PATTERN = /<%= partial: (?<path>.*?) %>/
|
|
24
|
+
|
|
25
|
+
class PartialFileNotFound < Geb::Error
|
|
26
|
+
MESSAGE = "Partial file not found".freeze
|
|
27
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
|
28
|
+
end # class PartialFileNotFound < Geb::Error
|
|
29
|
+
|
|
30
|
+
class PartialFileReadFailure < Geb::Error
|
|
31
|
+
MESSAGE = "PFailed to read the partial file.".freeze
|
|
32
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
|
33
|
+
end # class PartialFileReadFailure < Geb::Error
|
|
34
|
+
|
|
35
|
+
# define a class level cache for loaded partial objects
|
|
36
|
+
@@loaded_partials = {}
|
|
37
|
+
|
|
38
|
+
# class method to expire the partial cache
|
|
39
|
+
def self.expire_cache
|
|
40
|
+
@@loaded_partials = {}
|
|
41
|
+
end # def self.expire_cache
|
|
42
|
+
|
|
43
|
+
# class method to initialise a partial if it is not already loaded, otherwise, return the cached partial
|
|
44
|
+
# @param partial_path [String] the path to the partial file
|
|
45
|
+
# @return [Geb::Partial] the partial object
|
|
46
|
+
def self.load(partial_path)
|
|
47
|
+
|
|
48
|
+
# initialise a return partial object
|
|
49
|
+
return_partial = nil
|
|
50
|
+
|
|
51
|
+
# check if the partial is already loaded
|
|
52
|
+
if @@loaded_partials.key?(partial_path)
|
|
53
|
+
|
|
54
|
+
# return the cached partial
|
|
55
|
+
Geb.log " - using cached partial: #{partial_path}"
|
|
56
|
+
return_partial = @@loaded_partials[partial_path]
|
|
57
|
+
|
|
58
|
+
else
|
|
59
|
+
|
|
60
|
+
# create a new partial object
|
|
61
|
+
return_partial = Partial.new(partial_path)
|
|
62
|
+
|
|
63
|
+
# add the partial to the cache
|
|
64
|
+
@@loaded_partials[partial_path] = return_partial
|
|
65
|
+
|
|
66
|
+
end # if else
|
|
67
|
+
|
|
68
|
+
# return the partial object
|
|
69
|
+
return return_partial
|
|
70
|
+
|
|
71
|
+
end # def self.load
|
|
72
|
+
|
|
73
|
+
# class method to process partials in a page
|
|
74
|
+
# @param site_path [String] the path to the site
|
|
75
|
+
# @param page_content [String] the content of the page
|
|
76
|
+
# @return [Array] an array containing the number of partials found and the page content
|
|
77
|
+
# @raise [PartialFileNotFound] if the partial file does not exist
|
|
78
|
+
# @raise [PartialFileReadFailure] if the partial file could not be read
|
|
79
|
+
def self.process_partials(site_path, page_content)
|
|
80
|
+
|
|
81
|
+
# initialise a counter to count the number of partials found on the page
|
|
82
|
+
partial_count = 0
|
|
83
|
+
|
|
84
|
+
# initialize return page content
|
|
85
|
+
return_page_content = page_content.dup
|
|
86
|
+
|
|
87
|
+
# scan the page content for partials
|
|
88
|
+
return_page_content.gsub!(PARTIAL_PATTERN) do |match|
|
|
89
|
+
|
|
90
|
+
# match the partial relative and full paths
|
|
91
|
+
partial_file_path = match.match(PARTIAL_PATTERN)[:path].strip
|
|
92
|
+
partial_file_full_path = File.join(site_path, partial_file_path)
|
|
93
|
+
|
|
94
|
+
# load the partial object
|
|
95
|
+
partial = Partial.load(partial_file_full_path)
|
|
96
|
+
|
|
97
|
+
# increment the partial count
|
|
98
|
+
partial_count += 1
|
|
99
|
+
|
|
100
|
+
# return the partial content
|
|
101
|
+
partial.content
|
|
102
|
+
|
|
103
|
+
end # page_content.scan(PARTIAL_PATTERN) do |match|
|
|
104
|
+
|
|
105
|
+
# return the array of partial paths
|
|
106
|
+
return partial_count, return_page_content
|
|
107
|
+
|
|
108
|
+
end # def self.extract_partial_paths
|
|
109
|
+
|
|
110
|
+
# @!attribute [r] path
|
|
111
|
+
# @return [String] the path to the partial file
|
|
112
|
+
attr_reader :path
|
|
113
|
+
|
|
114
|
+
# @!attribute [r] content
|
|
115
|
+
# @return [String] the content of the partial file
|
|
116
|
+
attr_reader :content
|
|
117
|
+
|
|
118
|
+
# initialise a new partial object
|
|
119
|
+
# @param partial_path [String] the path to the partial file
|
|
120
|
+
# @raise [PartialFileNotFound] if the partial file does not exist
|
|
121
|
+
# @raise [PartialFileReadFailure] if the partial file could not be read
|
|
122
|
+
# @return [Geb::Partial] the partial object
|
|
123
|
+
def initialize(partial_path)
|
|
124
|
+
|
|
125
|
+
# set the partial path
|
|
126
|
+
@path = partial_path
|
|
127
|
+
@content = nil
|
|
128
|
+
|
|
129
|
+
# check if the partial file exists
|
|
130
|
+
raise PartialFileNotFound.new(partial_path) unless partial_file_exists?()
|
|
131
|
+
|
|
132
|
+
Geb.log " - loading partial: #{@path}"
|
|
133
|
+
|
|
134
|
+
# read the template file, raise an error if the file could not be read
|
|
135
|
+
begin
|
|
136
|
+
@content = File.read(partial_path)
|
|
137
|
+
rescue => e
|
|
138
|
+
raise PartialFileReadFailure.new(e.message)
|
|
139
|
+
end # begin
|
|
140
|
+
|
|
141
|
+
end # def initialize
|
|
142
|
+
|
|
143
|
+
# check if the partial file exists
|
|
144
|
+
# @return [Boolean] true if the partial file exists, otherwise false
|
|
145
|
+
def partial_file_exists?
|
|
146
|
+
return File.exist?(@path)
|
|
147
|
+
end # def template_file_exists?
|
|
148
|
+
|
|
149
|
+
end # class Partial
|
|
150
|
+
end # module Geb
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
|
|
2
|
+
# Geb Configuration File
|
|
3
|
+
# =======================
|
|
4
|
+
#
|
|
5
|
+
# This is a sample configuration file for the geb command line tool.
|
|
6
|
+
# You pretty much don't have to specify anything in this file, unless you want to
|
|
7
|
+
# customize the site. The default values are good enough for most sites.
|
|
8
|
+
#
|
|
9
|
+
# EVEN IF YOU DON"T SPECIFY ANYTHING IN THIS FILE, THIS CONFIG FILE MUST EXIST
|
|
10
|
+
# AT THE ROOT OF THE SITE DIRECTORY. OTHERWISE, THE GEB COMMANDS WILL NOT WORK.
|
|
11
|
+
# IT CAN BE EMPTY, BUT IT MUST EXIST. GEB DEMANDS IT.
|
|
12
|
+
#
|
|
13
|
+
# However, remote_uri and remote_path are required if you want to use
|
|
14
|
+
# the geb remote and upload commands. If you plan to upload the site on your own then
|
|
15
|
+
# you don't need to specify these values.
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
# Name of the site.
|
|
19
|
+
# If not specified, the default is the name of the directory where the site is located.
|
|
20
|
+
# Just for display purposes.
|
|
21
|
+
#site_name: "My Site"
|
|
22
|
+
|
|
23
|
+
# The remote_uri is the SSH URI of the remote server that you are deploying to.
|
|
24
|
+
# Geb remote and upload commands will use this URI to connect to the server.
|
|
25
|
+
# If you don't specify a remote_uri, geb remote and upload commands will not work.
|
|
26
|
+
# Typical format is username@server
|
|
27
|
+
#remote_uri: "user@server.com"
|
|
28
|
+
|
|
29
|
+
# The remote_path is the path on the remote server where the site is located.
|
|
30
|
+
# If you don't specify a remote_path, upload commands will not work.
|
|
31
|
+
#remote_path: "/path/to/site"
|
|
32
|
+
|
|
33
|
+
# Set the local web server port that the site will run on.
|
|
34
|
+
# Geb server command will use this port to start the local web server
|
|
35
|
+
# If you don't specify a port, geb server command auto selects a port
|
|
36
|
+
#local_port: 4000
|
|
37
|
+
|
|
38
|
+
# Specifies the output directory, this directory will be used to store the output of
|
|
39
|
+
# the build and release commands.
|
|
40
|
+
# the output directory is relative to the site directory.
|
|
41
|
+
# The default value is "output"
|
|
42
|
+
#output_dir: "output"
|
|
43
|
+
|
|
44
|
+
# Specifies the assets directory, this directory will be used to store the assets.
|
|
45
|
+
# The assets directory is relative to the site directory.
|
|
46
|
+
# The default value is "assets"
|
|
47
|
+
#assets_dir: "assets"
|
|
48
|
+
|
|
49
|
+
# Specifies the page extensions that are used in the site. This can be any text file extension.
|
|
50
|
+
# Default value is ['.md', '.markdown', '.html', '.htm', '.txt', '.js', '.css']
|
|
51
|
+
#page_extensions: ["html", "htm", "md", "markdown"]
|
|
52
|
+
|
|
53
|
+
# Template and partial identifier is a regular expression that is used to identify the template
|
|
54
|
+
# and partial files in the site. The default value is /^_/, any filename that starts with an underscore.
|
|
55
|
+
# These files are processed, but not included in the output directory, local or release.
|
|
56
|
+
# This setting does not impact template paths below, which are used to share the site as a template,
|
|
57
|
+
# which will include the template and partial files, if the template_paths includes them.
|
|
58
|
+
#template_and_partial_identifier: /^_/
|
|
59
|
+
|
|
60
|
+
# if you want to share the site as a template site, specify which files and directories
|
|
61
|
+
# are part of the template.
|
|
62
|
+
# When you create a new site, these files and directories will be copied to the new site
|
|
63
|
+
# If you don't specify template_paths, the site will not be shared as a template site and
|
|
64
|
+
# the geb release --with_template option will not work.
|
|
65
|
+
# Likewise, for other sites to use this site as a template, you must specify the template_paths.
|
|
66
|
+
# The site template files will be archived into geb-template.tar.gz file and put within
|
|
67
|
+
# the release directory.
|
|
68
|
+
# e.g. template_paths: ["assets", "shared", "*.html", "site.webmanifest"]
|
|
69
|
+
#template_paths: []
|
|
70
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
<!-- Global Site Tag (gtag-js) - Google Analytics -->
|
|
3
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
|
|
4
|
+
<script>
|
|
5
|
+
window.dataLayer = window.dataLayer || [];
|
|
6
|
+
function gtag() {databayer-push (arguments) ; }
|
|
7
|
+
gtag( 'js', new Date());
|
|
8
|
+
gtag( 'config', 'GA_TRACKING_ID' );
|
|
9
|
+
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!-- Bootstrap icons-->
|
|
2
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet" >
|
|
3
|
+
|
|
4
|
+
<!-- Bootstrap CSS -->
|
|
5
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
|
6
|
+
|
|
7
|
+
<!-- Custom CSS styles -->
|
|
8
|
+
<link href="_{site_url}_/assets/css/site.css" rel="stylesheet" />
|
|
9
|
+
|
|
10
|
+
<!--
|
|
11
|
+
The Bootstrap JavaScript bundle is not here, but is included in the footer of the page.
|
|
12
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
<!-- jQuery -->
|
|
16
|
+
<script src="https://code.jquery.com/jquery-3.7.1.slim.min.js" integrity="sha256-kmHvs0B+OpCW5GVHUNjv9rOmY0IvSIRcf7zGUDTDQM8=" crossorigin="anonymous"></script>
|
|
17
|
+
|
|
18
|
+
<!-- Custom Javascript -->
|
|
19
|
+
<script src="_{site_url}_/assets/js/site.js"></script>
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
<!-- Meta tags -->
|
|
3
|
+
<meta charset="utf-8" />
|
|
4
|
+
<meta name="generator" content="Geb 1.0.0" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
|
6
|
+
<meta name=”robots” content="index, follow" />
|
|
7
|
+
<meta name="description" content="_{title}_" />
|
|
8
|
+
<meta name="keywords" content="geb,geb static site,static site" />
|
|
9
|
+
<meta name="author" content="Geb, the Egyptian god of earth" />
|
|
10
|
+
|
|
11
|
+
<!-- Favicon and site icon -->
|
|
12
|
+
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="_{site_url}_/assets/images/apple-touch-icon.png" />
|
|
13
|
+
<link rel="icon" type="image/png" sizes="32x32" href="_{site_url}_/assets/images/favicon-32x32.png" />
|
|
14
|
+
<link rel="icon" type="image/png" sizes="16x16" href="_{site_url}_/assets/images/favicon-16x16.png" />
|
|
15
|
+
<link rel="icon" type="image/x-icon" href="_{site_url}_/assets/images/favicon.ico" />
|
|
16
|
+
<link rel="shortcut icon" type="image/x-icon" href="_{site_url}_/assets/images/favicon.ico" />
|
|
17
|
+
|
|
18
|
+
<!-- Site manifest -->
|
|
19
|
+
<link rel="canonical" href="_{site_url}_/_{relative_path}_" />
|
|
20
|
+
<link rel="manifest" type="image/png" href="/site.webmanifest" />
|
|
21
|
+
|
|
22
|
+
<!-- Open Graph -->
|
|
23
|
+
<meta property="og:type" content="website" />
|
|
24
|
+
<meta property="og:title" content="_{title}_" />
|
|
25
|
+
<meta property="og:description" content="_{title}_." />
|
|
26
|
+
<meta property="og:image" content="_{site_url}_/assets/images/og-thumb.png" />
|
|
27
|
+
|
|
28
|
+
<!-- Twitter Cards -->
|
|
29
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
30
|
+
<meta name="twitter:site" content="@twitter" />
|
|
31
|
+
<meta name="twitter:title" content="_{title}_" />
|
|
32
|
+
<meta name="twitter:description" content="_{title}_" />
|
|
33
|
+
<meta name="twitter:image" content="_{site_url}_/assets/images/twitter-thumb.png" />
|
|
34
|
+
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<title><%= insert: title %></title>
|
|
6
|
+
|
|
7
|
+
<%= partial: shared/partials/_analytics.html %>
|
|
8
|
+
<%= partial: shared/partials/_meta_tags.html %>
|
|
9
|
+
<%= partial: shared/partials/_global_assets.html %>
|
|
10
|
+
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
|
|
14
|
+
<%= partial: shared/partials/_header.html %>
|
|
15
|
+
<%= insert: content %>
|
|
16
|
+
<%= partial: shared/partials/_footer.html %>
|
|
17
|
+
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"","short_name":"","icons":[{"src":"/assets/images/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/assets/images/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|