aboutsummaryrefslogtreecommitdiff
path: root/captain
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2021-05-20 10:53:59 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2021-05-20 10:53:59 -0400
commit09e05b225bbea43d77ee1edfb896e5cdef43c145 (patch)
treec002b33ae0dfa6669d73f9316408a113de96c36c /captain
parent6e4ef96cb49b02ab3f2a9b8bc17dbacc6001c002 (diff)
downloadlevitating-09e05b225bbea43d77ee1edfb896e5cdef43c145.tar.gz
levitating-09e05b225bbea43d77ee1edfb896e5cdef43c145.zip
Added ability to extend templates if desired. Used in Home and About links.
Diffstat (limited to 'captain')
-rw-r--r--captain/levitating-captain.prj67
-rw-r--r--captain/response.f903
-rw-r--r--captain/template.f90148
-rw-r--r--captain/web.f9021
4 files changed, 198 insertions, 41 deletions
diff --git a/captain/levitating-captain.prj b/captain/levitating-captain.prj
index 0f996ef..4501070 100644
--- a/captain/levitating-captain.prj
+++ b/captain/levitating-captain.prj
@@ -10,123 +10,126 @@
"Folders":[],
"Name":"+bin",
"Files":[{
- "filename":".\\bin\\local.conf",
+ "filename":"bin/local.conf",
"enabled":"1"
},{
- "filename":".\\bin\\startlight.sh",
+ "filename":"bin/startlight.sh",
"enabled":"1"
}]
},{
"Folders":[],
"Name":"+common",
"Files":[{
- "filename":"..\\common\\jessl.f90",
+ "filename":"../common/jessl.f90",
"enabled":"1"
},{
- "filename":"..\\common\\network.F90",
+ "filename":"../common/network.F90",
"enabled":"1"
},{
- "filename":"..\\common\\protocol.f90",
+ "filename":"../common/protocol.f90",
"enabled":"1"
},{
- "filename":"..\\common\\request.f90",
+ "filename":"../common/request.f90",
"enabled":"1"
},{
- "filename":"..\\common\\utilities.F90",
+ "filename":"../common/utilities.F90",
"enabled":"1"
},{
- "filename":"..\\common\\wsa.f90",
+ "filename":"../common/wsa.f90",
"enabled":"0"
}]
},{
"Folders":[],
"Name":"+example",
"Files":[{
- "filename":".\\example\\levitating.conf",
+ "filename":"example/levitating.conf",
"enabled":"1"
}]
},{
"Folders":[],
"Name":"+sql",
"Files":[{
- "filename":".\\sql\\create.sql",
+ "filename":"sql/create.sql",
"enabled":"1"
},{
- "filename":".\\sql\\scan_instructions.sh",
+ "filename":"sql/scan_instructions.sh",
"enabled":"1"
}]
},{
"Folders":[],
"Name":"+templates",
"Files":[{
- "filename":".\\templates\\index.gmi",
+ "filename":"templates/home.html",
"enabled":"1"
},{
- "filename":".\\templates\\index.html",
+ "filename":"templates/index.gmi",
"enabled":"1"
},{
- "filename":".\\templates\\redirect.html",
+ "filename":"templates/index.html",
+ "enabled":"1"
+ },{
+ "filename":"templates/redirect.html",
"enabled":"1"
}]
}],
"Name":"+levitating-captain (levitating-captain)",
"Files":[{
- "filename":".\\api.f90",
+ "filename":"api.f90",
"enabled":"1"
},{
- "filename":".\\captain.f90",
+ "filename":"captain.f90",
"enabled":"1"
},{
- "filename":".\\config.f90",
+ "filename":"config.f90",
"enabled":"1"
},{
- "filename":".\\db.f90",
+ "filename":"db.f90",
"enabled":"1"
},{
- "filename":".\\external.f90",
+ "filename":"external.f90",
"enabled":"1"
},{
- "filename":".\\gemini.f90",
+ "filename":"gemini.f90",
"enabled":"1"
},{
- "filename":".\\http.f90",
+ "filename":"http.f90",
"enabled":"1"
},{
- "filename":".\\launch.f90",
+ "filename":"launch.f90",
"enabled":"1"
},{
- "filename":".\\log.f90",
+ "filename":"log.f90",
"enabled":"1"
},{
- "filename":".\\postutils.f90",
+ "filename":"postutils.f90",
"enabled":"1"
},{
- "filename":".\\queryutils.f90",
+ "filename":"queryutils.f90",
"enabled":"1"
},{
- "filename":".\\requtils.f90",
+ "filename":"requtils.f90",
"enabled":"1"
},{
- "filename":".\\response.f90",
+ "filename":"response.f90",
"enabled":"1"
},{
- "filename":".\\special.f90",
+ "filename":"special.f90",
"enabled":"1"
},{
- "filename":".\\sqlite.f90",
+ "filename":"sqlite.f90",
"enabled":"1"
},{
- "filename":".\\template.f90",
+ "filename":"template.f90",
"enabled":"1"
},{
- "filename":".\\web.f90",
+ "filename":"web.f90",
"enabled":"1"
}]
},
"Name":"levitating-captain (levitating-captain)",
"Options":{
"Compiler Options":{
- "Fortran Flags":"",
+ "Fortran Flags":"-DGNU",
"Link Flags":"-lsqlite3 -lssl -lcrypt",
"C Flags":""
},
diff --git a/captain/response.f90 b/captain/response.f90
index 748dd39..e743d0d 100644
--- a/captain/response.f90
+++ b/captain/response.f90
@@ -396,6 +396,7 @@ contains
end subroutine request_destroy
subroutine response_destroy(resp)
+ use utilities, only: delete_file
implicit none
class(response)::resp
@@ -410,7 +411,7 @@ contains
if(associated(resp%body_filename)) then
if(resp%temporary_file) then
- call unlink(resp%body_filename)
+ call delete_file(resp%body_filename)
end if
deallocate(resp%body_filename)
end if
diff --git a/captain/template.f90 b/captain/template.f90
index f3f6db1..ad4ea19 100644
--- a/captain/template.f90
+++ b/captain/template.f90
@@ -298,21 +298,106 @@ contains
call self%variables(i)%assign(name, value)
end subroutine template_assign_logical
+
+ function handle_template_extends(in_unit, extends_command) result(outfile)
+ use utilities, only: generate_temporary_filename
+ use config, only: template_filepath
+ implicit none
+
+ integer, intent(in)::in_unit
+ character(*), intent(in)::extends_command
+
+ character(len=:), pointer::outfile
+
+ integer::base_unit, out_unit
+ character(1024)::base_filename
+
+ character(256)::variable, varbuffer
+ character::this_char, last_char
- subroutine template_render(self, filename)
+ integer::i, istat
+
+ i = index(extends_command, "as")
+ if(i > 0) then
+ call template_filepath(trim(adjustl(extends_command(9:i-1))), base_filename)
+ variable = adjustl(extends_command(i+3:len_trim(extends_command)))
+
+ open(newunit=base_unit, file=trim(base_filename), status="old", &
+ form="unformatted", access="stream")
+
+ outfile => generate_temporary_filename()
+ open(newunit=out_unit, file=outfile, status="new", &
+ form="formatted", access="stream", action="write")
+
+ last_char = ' '
+ read(base_unit, iostat=istat) this_char
+ do while(istat == 0)
+
+ if(this_char == '{' .and. last_char == '{') then
+
+ varbuffer = '{{'
+
+ i = 2
+ do while(varbuffer(i-1:i) /= '}}' .and. istat == 0)
+ i = i + 1
+ read(base_unit, iostat=istat) varbuffer(i:i)
+ end do
+
+ ! Found our variable!
+ if( trim(variable) == trim(adjustl(varbuffer(4:i-3))) ) then
+
+ ! Write out the original input unit
+ read(in_unit, iostat=istat) this_char
+ do while(istat == 0)
+ write(out_unit, '(A1)', advance='no') this_char
+ read(in_unit, iostat=istat) this_char
+ end do
+
+ ! Not our variable
+ else
+
+ do i = 1, len_trim(varbuffer)
+ write(out_unit, '(A1)', advance='no') varbuffer(i:i)
+ end do
+
+ end if
+
+ last_char = ' '
+ this_char = ' '
+ else if(last_char == '{') then
+
+ write(out_unit, '(A1, A1)', advance='no') last_char, this_char
+
+ else if(this_char /= '{') then
+
+ write(out_unit, '(A1)', advance='no') this_char
+
+ end if
+
+ last_char = this_char
+ read(base_unit, iostat=istat) this_char
+ end do
+
+ close(base_unit)
+ close(out_unit)
+
+ end if
+
+ end function handle_template_extends
+
+ recursive subroutine template_render(self, filename, input_tempfile)
use logging
+ use utilities, only: delete_file
implicit none
class(template)::self
- character(*), intent(in), optional::filename
+ character(*), intent(in), optional::filename, input_tempfile
character::this_char, last_char
character(len=2)::running_pair, closing_pair
character(256)::brace_internals
character(len=:), pointer::replacement
- integer(kind=8)::input_position
-
logical::writing_now
integer::input, istat, i, unum
@@ -320,12 +405,18 @@ contains
if(present(filename)) then
allocate(character(len=len_trim(filename)) :: self%output_filename)
self%output_filename = trim(filename)
- else
+ else if(.not. associated(self%output_filename)) then
call self%generate_output_filename()
end if
- open(newunit=unum, file=trim(self%output_filename), status="new", form="formatted", access="stream", action="write")
- open(newunit=input, file=trim(self%base_filename), status="old", form="unformatted", access="stream")
+ open(newunit=unum, file=trim(self%output_filename), status="unknown", form="formatted", access="stream", action="write")
+
+ ! We may be working with a temporary file after a 'extends' tag
+ if(present(input_tempfile)) then
+ open(newunit=input, file=trim(input_tempfile), status="old", form="unformatted", access="stream")
+ else
+ open(newunit=input, file=trim(self%base_filename), status="old", form="unformatted", access="stream")
+ end if
writing_now = .true.
@@ -374,6 +465,49 @@ contains
end if
+ else if(running_pair == '{%') then
+
+ closing_pair = '%}'
+ brace_internals = ' '
+
+ read(input, iostat=istat) this_char
+ i = 1
+ do while(istat == 0 .and. (running_pair /= closing_pair))
+ brace_internals(i:i) = this_char
+
+ i = i + 1
+ last_char = this_char
+ read(input, iostat=istat) this_char
+ running_pair = last_char//this_char
+ end do
+ brace_internals(i-1:i-1) = ' ' ! Remove trailing bracket
+ brace_internals = adjustl(brace_internals)
+
+ ! Parse the command
+ if(brace_internals(1:8) == 'extends ') then
+
+ ! Replacement will be a new file to parse through this engine
+ replacement => handle_template_extends(input ,trim(brace_internals))
+
+ ! Close the current set of files before retrying the rendering
+ close(unum)
+ close(input)
+
+ ! Re-render using the constructed tempfile
+ if(associated(replacement)) then
+ call write_log("replacement template: "//trim(replacement), LOG_DEBUG)
+ call template_render(self, input_tempfile=replacement)
+ call write_log("template output: "//trim(self%output_filename), LOG_DEBUG)
+ ! It was temporary
+ call delete_file(replacement)
+ deallocate(replacement)
+ end if
+
+ ! Stop rendering - it was handled above
+ return
+
+ end if
+
else if(last_char == '{') then
write(unum, '(A1)', advance='no') last_char
write(unum, '(A1)', advance='no') this_char
diff --git a/captain/web.f90 b/captain/web.f90
index bb225ac..cc3a552 100644
--- a/captain/web.f90
+++ b/captain/web.f90
@@ -569,6 +569,7 @@ contains
type(request), intent(in)::req
type(response)::resp
+ character(64)::template_to_use
character(1024)::template_file
type(template)::page
character(64)::first
@@ -576,7 +577,25 @@ contains
character(len=:), pointer::contents
character(128)::job_page_title
- call template_filepath("index.html", template_file)
+
+ if(trim(req%location) == "/" .or. &
+ trim(req%location) == "/index.html" .or. &
+ trim(req%location) == "/home.html") &
+ then
+
+ template_to_use = "home.html"
+
+ else if(trim(req%location) == "/about.html") then
+
+ template_to_use = "about.html"
+
+ else
+
+ template_to_use = "index.html"
+
+ end if
+
+ call template_filepath(template_to_use, template_file)
call write_log("Template base path is: "//trim(template_file), LOG_DEBUG)
call page%init(trim(template_file))