<commit_before>// Copyright 2014 <NAME>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package templates

import (
	"fmt"
	"github.com/andreaskoch/allmark2/model"
	"strings"
	"text/template"
)

const (
	// Template placholders
	ChildTemplatePlaceholder = "@childtemplate"

	// Template names
	MasterTemplateName = "master"
	ErrorTemplateName  = "error"

	OpenSearchDescriptionTemplateName = "opensearchdescription"

	SitemapTemplateName        = "sitemap"
	SitemapContentTemplateName = "sitemapcontent"

	XmlSitemapTemplateName        = "xmlsitemap"
	XmlSitemapContentTemplateName = "xmlsitemapcontent"

	RssFeedTemplateName        = "rssfeed"
	RssFeedContentTemplateName = "rssfeedcontent"

	TagmapTemplateName        = "tagmap"
	TagmapContentTemplateName = "tagmapcontent"

	SearchTemplateName        = "search"
	SearchContentTemplateName = "searchcontent"

	ConversionTemplateName = "converter"
)

type Provider struct {
	Modified chan bool

	folder    string
	templates map[string]*Template
	cache     map[string]*template.Template
}

func NewProvider(templateFolder string) Provider {

	// intialize the templates
	templates := make(map[string]*Template)

	templates[MasterTemplateName] = NewTemplate(templateFolder, MasterTemplateName, masterTemplate)
	templates[ErrorTemplateName] = NewTemplate(templateFolder, ErrorTemplateName, errorTemplate)

	templates[OpenSearchDescriptionTemplateName] = NewTemplate(templateFolder, OpenSearchDescriptionTemplateName, openSearchDescriptionTemplate)

	templates[TagmapTemplateName] = NewTemplate(templateFolder, TagmapTemplateName, tagmapTemplate)
	templates[TagmapContentTemplateName] = NewTemplate(templateFolder, TagmapContentTemplateName, tagmapContentTemplate)

	templates[SitemapTemplateName] = NewTemplate(templateFolder, SitemapTemplateName, sitemapTemplate)
	templates[SitemapContentTemplateName] = NewTemplate(templateFolder, SitemapContentTemplateName, sitemapContentTemplate)

	templates[XmlSitemapTemplateName] = NewTemplate(templateFolder, XmlSitemapTemplateName, xmlSitemapTemplate)
	templates[XmlSitemapContentTemplateName] = NewTemplate(templateFolder, XmlSitemapContentTemplateName, xmlSitemapContentTemplate)

	templates[RssFeedTemplateName] = NewTemplate(templateFolder, RssFeedTemplateName, rssFeedTemplate)
	templates[RssFeedContentTemplateName] = NewTemplate(templateFolder, RssFeedContentTemplateName, rssFeedContentTemplate)

	templates[SearchTemplateName] = NewTemplate(templateFolder, SearchTemplateName, searchTemplate)
	templates[SearchContentTemplateName] = NewTemplate(templateFolder, SearchContentTemplateName, searchContentTemplate)

	templates[model.TypeDocument.String()] = NewTemplate(templateFolder, model.TypeDocument.String(), documentTemplate)
	templates[model.TypeLocation.String()] = NewTemplate(templateFolder, model.TypeLocation.String(), locationTemplate)
	templates[model.TypeMessage.String()] = NewTemplate(templateFolder, model.TypeMessage.String(), messageTemplate)
	templates[model.TypeRepository.String()] = NewTemplate(templateFolder, model.TypeRepository.String(), repositoryTemplate)
	templates[model.TypePresentation.String()] = NewTemplate(templateFolder, model.TypePresentation.String(), presentationTemplate)

	templates[ConversionTemplateName] = NewTemplate(templateFolder, ConversionTemplateName, converterTemplate)

	// create the provider
	provider := Provider{
		folder:    templateFolder,
		templates: templates,
		cache:     make(map[string]*template.Template),
	}

	return provider
}

func (provider *Provider) GetFullTemplate(hostname, templateName string) (*template.Template, error) {

	t, err := provider.getParsedTemplate(templateName, true)
	if err != nil {
		panic(err)
		return nil, err
	}

	// override template functions
	t.Funcs(provider.getTemplateFunctions(hostname))

	return t, nil
}

func (provider *Provider) GetSubTemplate(hostname, templateName string) (*template.Template, error) {
	t, err := provider.getParsedTemplate(templateName, false)
	if err != nil {
		return nil, err
	}

	// override template functions
	t.Funcs(provider.getTemplateFunctions(hostname))

	return t, nil
}

func (provider *Provider) getTemplateFunctions(hostname string) map[string]interface{} {

	// Get the current hostname
	getHostname := func() string {
		return hostname
	}

	// get the absolute url for a given (relative) uri
	getAbsoluteUrl := func(uri string) string {

		// sanatize
		uri = strings.TrimSpace(uri)

		// add prefix
		if !strings.HasPrefix(uri, "/") {
			uri = "/" + uri
		}

		return "//" + getHostname() + uri
	}

	return map[string]interface{}{
		"hostname": getHostname,<commit_msg>Assume http for the "absolute" template function for now (allmark2 doesn't support https at the momment, but once its supported we might have to change the method signature to pass a request object or so)<commit_after>// Copyright 2014 <NAME>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package templates

import (
	"fmt"
	"github.com/andreaskoch/allmark2/model"
	"strings"
	"text/template"
)

const (
	// Template placholders
	ChildTemplatePlaceholder = "@childtemplate"

	// Template names
	MasterTemplateName = "master"
	ErrorTemplateName  = "error"

	OpenSearchDescriptionTemplateName = "opensearchdescription"

	SitemapTemplateName        = "sitemap"
	SitemapContentTemplateName = "sitemapcontent"

	XmlSitemapTemplateName        = "xmlsitemap"
	XmlSitemapContentTemplateName = "xmlsitemapcontent"

	RssFeedTemplateName        = "rssfeed"
	RssFeedContentTemplateName = "rssfeedcontent"

	TagmapTemplateName        = "tagmap"
	TagmapContentTemplateName = "tagmapcontent"

	SearchTemplateName        = "search"
	SearchContentTemplateName = "searchcontent"

	ConversionTemplateName = "converter"
)

type Provider struct {
	Modified chan bool

	folder    string
	templates map[string]*Template
	cache     map[string]*template.Template
}

func NewProvider(templateFolder string) Provider {

	// intialize the templates
	templates := make(map[string]*Template)

	templates[MasterTemplateName] = NewTemplate(templateFolder, MasterTemplateName, masterTemplate)
	templates[ErrorTemplateName] = NewTemplate(templateFolder, ErrorTemplateName, errorTemplate)

	templates[OpenSearchDescriptionTemplateName] = NewTemplate(templateFolder, OpenSearchDescriptionTemplateName, openSearchDescriptionTemplate)

	templates[TagmapTemplateName] = NewTemplate(templateFolder, TagmapTemplateName, tagmapTemplate)
	templates[TagmapContentTemplateName] = NewTemplate(templateFolder, TagmapContentTemplateName, tagmapContentTemplate)

	templates[SitemapTemplateName] = NewTemplate(templateFolder, SitemapTemplateName, sitemapTemplate)
	templates[SitemapContentTemplateName] = NewTemplate(templateFolder, SitemapContentTemplateName, sitemapContentTemplate)

	templates[XmlSitemapTemplateName] = NewTemplate(templateFolder, XmlSitemapTemplateName, xmlSitemapTemplate)
	templates[XmlSitemapContentTemplateName] = NewTemplate(templateFolder, XmlSitemapContentTemplateName, xmlSitemapContentTemplate)

	templates[RssFeedTemplateName] = NewTemplate(templateFolder, RssFeedTemplateName, rssFeedTemplate)
	templates[RssFeedContentTemplateName] = NewTemplate(templateFolder, RssFeedContentTemplateName, rssFeedContentTemplate)

	templates[SearchTemplateName] = NewTemplate(templateFolder, SearchTemplateName, searchTemplate)
	templates[SearchContentTemplateName] = NewTemplate(templateFolder, SearchContentTemplateName, searchContentTemplate)

	templates[model.TypeDocument.String()] = NewTemplate(templateFolder, model.TypeDocument.String(), documentTemplate)
	templates[model.TypeLocation.String()] = NewTemplate(templateFolder, model.TypeLocation.String(), locationTemplate)
	templates[model.TypeMessage.String()] = NewTemplate(templateFolder, model.TypeMessage.String(), messageTemplate)
	templates[model.TypeRepository.String()] = NewTemplate(templateFolder, model.TypeRepository.String(), repositoryTemplate)
	templates[model.TypePresentation.String()] = NewTemplate(templateFolder, model.TypePresentation.String(), presentationTemplate)

	templates[ConversionTemplateName] = NewTemplate(templateFolder, ConversionTemplateName, converterTemplate)

	// create the provider
	provider := Provider{
		folder:    templateFolder,
		templates: templates,
		cache:     make(map[string]*template.Template),
	}

	return provider
}

func (provider *Provider) GetFullTemplate(hostname, templateName string) (*template.Template, error) {

	t, err := provider.getParsedTemplate(templateName, true)
	if err != nil {
		panic(err)
		return nil, err
	}

	// override template functions
	t.Funcs(provider.getTemplateFunctions(hostname))

	return t, nil
}

func (provider *Provider) GetSubTemplate(hostname, templateName string) (*template.Template, error) {
	t, err := provider.getParsedTemplate(templateName, false)
	if err != nil {
		return nil, err
	}

	// override template functions
	t.Funcs(provider.getTemplateFunctions(hostname))

	return t, nil
}

func (provider *Provider) getTemplateFunctions(hostname string) map[string]interface{} {

	// Get the current hostname
	getHostname := func() string {
		return hostname
	}

	// get the absolute url for a given (relative) uri
	getAbsoluteUrl := func(uri string) string {

		// sanatize
		uri = strings.TrimSpace(uri)

		// add prefix
		if !strings.HasPrefix(uri, "/") {
			uri = "/" + uri
		}

		return "http://" + getHostname() + uri
	}

	return map[string]interface{}{
		"hostname": getHostname,
{'fraction_non_alphanumeric': 0.09107031087001878, 'fraction_numerical': 0.0011475067807218862, 'mean_word_length': 6.531029065200314, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '903113', 'n_tokens_mistral': 2721, 'n_tokens_neox': 2619, 'n_words': 580}