Skip to content

Gharib110/booking_room_system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BookingManagementSystem

An application for manage a website that rent rooms for any type of meetings . that have two type such as generals or majors rooms for any type of porpuses. I use html template library for generating and parsing HTML templates.


Rendering HTML Templates

I use native golang libraries for creating and caching all templates for every pages that My app have.
Creating cache from Templates:

  • First I get all my templates by regex then I create a template for each of them and parse them.
  • Second I get all layouts that I designed for applying on every page that I have with ParseGlob and parse with every template that I created.
  • Third I return my templates as a map[string]*template.Template
// CreateCacheTemplates for rendering and caching the templates
func CreateCacheTemplates() (map[string]*template.Template, error) {
   myCache := map[string]*template.Template{}

   pages, err := filepath.Glob("./templates/*.page.tmpl")
   if err != nil {

   	log.Println("We have some error with finding the pages : ", err.Error())
   	return myCache, err
   }

   for _, page := range pages {

   	pageName := filepath.Base(page)
   	parsedTmpl, err := template.New(pageName).Funcs(functions).ParseFiles(page)
   	if err != nil {

   		log.Println("We have some problem during parsing the templates : ", err.Error())
   		return myCache, err
   	}

   	layouts, err := filepath.Glob("./templates/*.layout.tmpl")
   	if err != nil {

   		log.Println("We have some problems with finding matches layouts : ", err.Error())
   		return myCache, err
   	}

   	if len(layouts) > 0 {

   		parsedTmpl, err = parsedTmpl.ParseGlob("./templates/*.layout.tmpl")
   		if err != nil {

   			log.Println("We have some problems with parsing layouts with pages : ", err.Error())
   			return nil, err
   		}

   		myCache[pageName] = parsedTmpl
   	}
   }

   return myCache, nil
}

Rendering HTML Templates

I implement two function for rendering a html template :

  • First I get information and structures that I need to such as http.ResponseWriter
  • Second pull out the target template from my template cache then execute it with default function that I use for using some information And also CSRF token for preventing cross-site-request-forgery
// AddDefaultData use for adding default data to every single *.page.tmpl for using it in them
func AddDefaultData(td *models.TemplateData, r *http.Request) *models.TemplateData {
	td.Flash = appConfig.Session.PopString(r.Context(), "flash")
	td.Warning = appConfig.Session.PopString(r.Context(), "warning")
	td.Error = appConfig.Session.PopString(r.Context(), "error")

	if appConfig.Session.Exists(r.Context(), "user_id") {
		td.IsAuthenticated = 1
	} else {
		td.IsAuthenticated = 0
	}

	td.CSFRToken = nosurf.Token(r)
	return td
}
// RenderByCacheTemplates render a go template by templatesCache
func RenderByCacheTemplates(w *http.ResponseWriter, r *http.Request, tmpl string, tmplData *models.TemplateData) {
   cacheTmpls := appConfig.TemplateCache

   Tmpl, ok := cacheTmpls[tmpl]
   if ok == false {

   	_, _ = fmt.Fprintf(*w, "We do not be able to find your page !")
   	log.Println("The tmpl did not found : ", tmpl)
   } else {

   	tmplBuff := new(bytes.Buffer)
   	err := Tmpl.Execute(tmplBuff, AddDefaultData(tmplData, r))
   	if err != nil {

   		log.Println("Error occurred during Executing the template !")
   		_, _ = fmt.Fprintf(*w, "Error occurred during loading the page ! => \n"+err.Error())
   	} else {

   		_, err := tmplBuff.WriteTo(*w)
   		if err != nil {

   			log.Println("Error occurred during writing the buffer to responseWriter !")
   			_, _ = fmt.Fprintf(*w, "Error occurred during loading the page !")
   		}
   	}
   }
}

Reservation E-mail

I use a goroutine that I run it at the beginning of the application to get the MailData through a channel then pass it to a function that I used it for sending email to a specific mail.

//MailData using for sending mail management structure
type MailData struct {
To      string
From    string
Subject string
Content string
}

func listenToMail() {
	go func() {
		for {
			msg := <-appConfig.MailChan
			sendMsg(msg)
		}
	}()
}

func sendMsg(msg models.MailData) {
	server := mail.NewSMTPClient()
	server.Host = "localhost"
	server.Port = 1025
	server.KeepAlive = false
	server.SendTimeout = time.Second * 10
	server.ConnectTimeout = time.Second * 10

	client, err := server.Connect()
	if err != nil {
		log.Println("Some error in getting the client from smtp server : " + err.Error() + "\n")
		return
	}

	mailTemplate, err := ioutil.ReadFile("./html_sources/basic_email_template.html")
	if err != nil {
		log.Println("Error in reading the html template : " + err.Error() + "\n")
	}

	mailStr := string(mailTemplate)
	mailStr = strings.Replace(mailStr, "[%name%]", msg.To, 2)
	mailStr = strings.Replace(mailStr, "[%subject%]", msg.Subject, 2)
	mailStr = strings.Replace(mailStr, "[%content%]", msg.Content, 2)

	email := mail.NewMSG()
	email.SetSubject(msg.Subject)
	email.SetFrom(msg.From)
	email.SetFrom(msg.To)
	email.SetBody(mail.TextHTML, mailStr)

	err = email.Send(client)
	if err != nil {
		log.Println("Error in sending mail : " + err.Error() + "\n")
		return
	}
}


Special Thanks

I should say thank you to these legend developers for creating and maintaining fabulous packages.

        github.com/alexedwards/scs/v2 v2.4.0
	github.com/asaskevich/govalidator
	github.com/go-chi/chi v1.5.4
	github.com/jackc/pgconn v1.8.1
	github.com/jackc/pgx/v4 v4.11.0
	github.com/justinas/nosurf v1.1.1
	github.com/xhit/go-simple-mail/v2 v2.9.1

Releases

No releases published

Packages

No packages published

Languages