Odania-IT/odania-core

View on GitHub
app/controllers/template_controller.rb

Summary

Maintainability
C
7 hrs
Test Coverage
require 'odania'

class TemplateController < ApplicationController
    include EntryConcern

    # Only rendering template might result in 200 instead of 404. Is there a way to let varnish send a 404 if one page fails?
    def page
        req_host = params[:req_host]
        req_url = params[:req_url]
        subdomain_config = Odania.plugin.get_subdomain_config(req_host)

        if subdomain_config.nil?
            domain_info = PublicSuffix.parse(req_host)
            domain = domain_info.domain
            valid_domain_config = Odania.plugin.get_valid_domain_config

            # Is this a valid domain?
            valid_domains = valid_domain_config['valid_domains']
            if valid_domains[domain].nil?
                # Redirect to default domain
                valid_domains = valid_domain_config['default_domains'].empty? ? valid_domain_config['valid_domains'] : valid_domain_config['default_domains']
                domain = valid_domains.keys.first
                return render plain: 'No valid domain defined!', status: :service_unavailable if domain.nil?
                subdomain = valid_domains[domain].first
                return redirect_to "http://#{subdomain}.#{domain}"
            else
                # Redirect to valid subdomain
                default_domains = valid_domain_config['default_domains']
                subdomain = default_domains[domain].nil? ? nil : default_domains[domain].first
                subdomain = valid_domains[domain].first if subdomain.nil?
                return redirect_to "http://#{subdomain}.#{domain}"
            end
        end

        # Identify layout
        domain = subdomain_config['domain']
        selected_layout = subdomain_config['layout']
        style = '_general'
        partial_name = subdomain_config['styles'][style]['entry_point']
        logger.info "Selected Layout: '#{selected_layout}' [#{partial_name}]"

        result = $elasticsearch.search index: select_index('partial'), type: 'partial', body: {
            sort: {
                _score: 'desc'
            },
            query: {
                filtered: {
                    filter: {
                        bool: {
                            must: [
                                {term: {partial_name: partial_name}}
                            ]
                        }
                    },
                    query: {
                        bool: {
                            should: [
                                {match: {full_domain: {query: req_host, boost: 10}}},
                                {match: {full_domain: {query: domain, boost: 6}}},
                                {match: {domain: '_general'}}
                            ]
                        }
                    }
                }
            }
        }

        total_hits = result['hits']['total']
        logger.info "Layout total hits: #{total_hits}"

        if total_hits.eql? 0
            @error_msg = 'Sorry.... there was an internal error and we could not find the required template!'
            return error :service_unavailable
        end

        hits = result['hits']['hits']
        hit = hits.first
        source = hit['_source']
        logger.info "Layout Best Hit: [#{hit['_score']}] #{source['full_domain']} #{source['full_path']}"
        template = source['content']

        data = {
            req_url: req_url,
            locale: locale_from_url(req_url)
        }

        extra_partials = {
            'content' => "http://internal.core/template/content?req_url=#{req_url}&req_host=#{req_host}&locale=#{data[:locale]}"
        }

        response.headers['X-Do-Esi'] = true
        odania_template = OdaniaCore::Erb.new(template, subdomain_config, build_domain_query(domain, req_host), data, extra_partials)
        render html: odania_template.render.html_safe
    end

    def content
        req_host = params[:req_host]
        req_url = params[:req_url]
        locale = params[:locale]
        subdomain_config = Odania.plugin.get_subdomain_config(req_host)

        result = render_direct_page 'web', req_host, req_url, subdomain_config, {req_url: req_url, locale: locale}
        return render html: result if result

        # Try list view
        logger.debug "No direct page found for #{req_url} [#{req_host}]"
        return error unless subdomain_config['config']['render_list_view']
        @domain = subdomain_config['domain']

        # Do we have pages belonging under this path?
        query = {
            from: 0,
            size: 10,
            sort: {
                _score: 'desc'
            },
            query: build_filtered_domain_query(@domain, req_host, {
                bool: {
                    must: [
                        {prefix: {path: req_url}},
                        {term: {released: true}},
                        {term: {view_in_list: true}}
                    ]
                }
            })
        }
        result = search 'web', query
        @total_hits = result['total']
        @hits = result['hits']

        return error if @total_hits.eql? 0

        # Get list view template from layout
        partial_name = get_partial_template subdomain_config['partials']['list_view']
        result = render_direct_page 'partial', req_host, partial_name, subdomain_config, {hits: @hits, total_hits: @total_hits, req_url: req_url, locale: locale}
        logger.info "rendering partial #{result.inspect}"
        render html: result if result
    end

    def partial
        req_host = params[:req_host]
        partial_name = params[:partial_name]
        locale = params[:locale]
        data = params[:data]
        subdomain_config = Odania.plugin.get_subdomain_config(req_host)

        el_partial_name = get_partial_template subdomain_config['partials'][partial_name]
        result = render_direct_page 'partial', req_host, el_partial_name, subdomain_config, {locale: locale, data: data}
        return error if result.nil?
        render html: result
    end

    def error(status=:not_found)
        @error_msg = 'Sorry.... we could not find the requested page.' if @error_msg.nil?

        response.headers['X-Do-Esi'] = true
        render status: status, action: :error
    end

    private

    def render_direct_page(type, req_host, path, subdomain_config, data)
        domain_info = PublicSuffix.parse(req_host)
        domain = domain_info.domain

        result = get_entry_by_path(type, domain, req_host, path)
        total_hits = result['total']
        logger.info "total_hits: #{total_hits}"

        return nil if total_hits.eql? 0
        hits = result['hits']
        hit = hits.first
        template = hit['_source']['content']

        response.headers['X-Do-Esi'] = true
        odania_template = OdaniaCore::Erb.new(template, subdomain_config, build_domain_query(domain, req_host), data)
        odania_template.render.html_safe
    end

    def get_entry_by_path(type, domain, req_host, path)
        must_query = 'web'.eql?(type) ? [{term: {released: true}}, {term: {path: path}}] : [{term: {partial_name: path}}]

        query = {
            from: 0,
            size: 10,
            sort: {
                _score: 'desc'
            },
            query: build_filtered_domain_query(domain, req_host, {
                bool: {
                    must: must_query
                }
            })
        }

        logger.info query

        search type, query
    end

    def get_partial_template(partial)
        return '' if partial.nil?
        partial['template']
    end

    def locale_from_url(req_url)
        req_url = req_url.split('/')
        req_url.shift
        req_url[0].nil? ? 'en' : req_url[0]
    end
end