From 09e05b225bbea43d77ee1edfb896e5cdef43c145 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Thu, 20 May 2021 10:53:59 -0400 Subject: Added ability to extend templates if desired. Used in Home and About links. --- captain/levitating-captain.prj | 67 ++++++++++--------- captain/response.f90 | 3 +- captain/template.f90 | 148 +++++++++++++++++++++++++++++++++++++++-- captain/web.f90 | 21 +++++- 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)) -- cgit v1.2.3