template_generator.rb 14.7 KB
module Kanjai
  module TemplateGenerator
    def self.subpart_generate(session, domain, page_template, type, elements, hash_value = nil, page_content_id = nil)
      session ||= {}
      @doc = Nokogiri::HTML::DocumentFragment.parse ""

      @original_hash_value = hash_value
      @original_hash_value ||= {}

      @page_content_id = page_content_id
      @page_content = page_content_id.present? ? Kanjai::PageContent.find(page_content_id) : nil

      Nokogiri::HTML::Builder.with(@doc) do |subparts|
        @repeat_type_index = {}
        if type == "subMenuTemplate"
          type = "menu" 
          current_page = nil
          if session[:current_page_id]
            current_page = Kanjai::Page.find_by_id(session[:current_page_id])
            while current_page && current_page.parent && current_page.page_template == current_page.parent.page_template
              current_page = current_page.parent
            end
          end
          TemplateGenerator.method("#{type}_generator").call(session, domain, elements, subparts, @original_hash_value[0], current_page)
        else
          TemplateGenerator.method("#{type}_generator").call(session, domain, elements, subparts, @original_hash_value[0])
        end
      end

      @doc.css("img[@src]").each do |x|
        image_link = x['src']
        unless image_link.match(/^(http:|https:)/)
          x['src'] = page_template.template_content_url + image_link
        end
      end

      @doc.to_html
    end



    def self.menu_generator(session, domain, elements, subparts, hash_value, current_page = nil)
        elements.each do |item|
          case item[:name]
            when 'text'
              content = item[:source]
              #if current_page
              #  content = content.gsub('###link###', current_page.menu_url('http://', lang = nil))
              #       .gsub('###title###', current_page.lang_attributes(domain.page_langs.default, :title))
              #end
              subparts << content
            when 'repeat'
              #get template for normal state, active state and separator
              normal_state = item[:children].select{|item2| item2[:name] == 'normal' }.first
              active_state = item[:children].select{|item2| item2[:name] == 'active' }.first
              separator = item[:children].select{|item2| item2[:name] == 'separator' }.first
              next_level = item[:children].select{|item2| item2[:name] == 'level' }.first

              normal_state_template = active_state_template = separator_template = ''

              if normal_state
                doc_normal_state = Nokogiri::HTML::DocumentFragment.parse ""
                Nokogiri::HTML::Builder.with(doc_normal_state) do |repeat_part|
                  self.menu_generator(session, domain, normal_state[:children], repeat_part, nil)
                end
                normal_state_template = doc_normal_state.to_html
              end

              if active_state
                doc_active_state = Nokogiri::HTML::DocumentFragment.parse ""
                Nokogiri::HTML::Builder.with(doc_active_state) do |repeat_part|
                  self.menu_generator(session, domain, active_state[:children], repeat_part, nil)
                end
                active_state_template = doc_active_state.to_html
              end

              if separator
                doc_separator = Nokogiri::HTML::DocumentFragment.parse ""
                Nokogiri::HTML::Builder.with(doc_separator) do |repeat_part|
                  self.menu_generator(session, domain, separator[:children], repeat_part, nil)
                end
                separator_template = doc_separator.to_html
              end


              page_collection = Page.joins(:domain).where(kanjai_domains: {id: domain.id}).order(:position)

              if item[:attributes]["ids"].present?
                page_collection = page_collection.where('id in (?)', item[:attributes]["ids"])
              end


              unless item[:attributes]["root_id"].nil?
                root_id = item[:attributes]["root_id"].to_s

                root_id = nil if root_id.empty?

                page_collection = page_collection.where(:parent_id => root_id)
              end

              unless current_page.nil?
                page_collection = page_collection.where(:parent_id => current_page.id)
              end

              begin
                if !!UserSession
                  if UserSession.current_user
                    page_collection = page_collection.where(:private_flag => [true, false])
                                      .where(show_public_only: false)
                  else
                    page_collection = page_collection.where(private_flag: false)
                  end
                end
              rescue
                page_collection = page_collection.where(private_flag: false)
              end


              page_collection.each do |page|
                if page.children.length > 0 and next_level
                  subparts << item[:source]

                  self.menu_generator(session, domain, next_level[:children], subparts, nil, page)
                else

                  if session[:url] == page.lang_attributes(I18n.locale, :url)
                    if active_state_template.present?
                      subparts << active_state_template.gsub('###link###', page.menu_url(session[:scheme], lang = nil))
                                    .gsub('###title###', page.lang_attributes(I18n.locale, :title))
                    end
                  else
                    if normal_state_template.present?
                      subparts << normal_state_template.gsub('###link###', page.menu_url(session[:scheme], lang = nil))
                                                        .gsub('###title###', page.lang_attributes(I18n.locale, :title))
                    end
                  end

                  if separator_template.present? and page != page_collection.last
                    subparts << separator_template
                  end
                end


              end


            else
                attributes = item[:attributes]
                if current_page
                  p attributes
                end
                subparts.send(item[:name].to_s, attributes) do |next_subparts|
                  self.menu_generator(session, domain, item[:children], next_subparts, nil, current_page)
                end
          end

        end

    end

    def self.language_generator(session, domain, elements, subparts, hash_value)
      elements.each do |item|
        case item[:name]
          when 'text'
            lang = domain.page_langs.find_by_code(session[:current_locale])
            content = item[:source]
            content = content.gsub('###CURRENT_LANG_TITLE###', lang.title)
                        .gsub('###CURRENT_LANG_CODE###', lang.code)
            subparts << content
          when 'repeat'
            #get template for normal state, active state and separator
            item_state = item[:children].select{|item2| item2[:name] == 'item' }.first
            active_state = item[:children].select{|item2| item2[:name] == 'active' }.first

            if item_state
              doc_item_state = Nokogiri::HTML::DocumentFragment.parse ""
              Nokogiri::HTML::Builder.with(doc_item_state) do |repeat_part|
                self.language_generator(session, domain, item_state[:children], repeat_part, nil)
              end
              item_state_template = doc_item_state.to_html
            end

            if active_state
              doc_active_state = Nokogiri::HTML::DocumentFragment.parse ""
              Nokogiri::HTML::Builder.with(doc_active_state) do |repeat_part|
                self.language_generator(session, domain, active_state[:children], repeat_part, nil)
              end
              active_state_template = doc_active_state.to_html
            end


            page_data = PageDatum.where(:url => session[:url], :lang => session[:current_locale]).first
            if page_data
              page = page_data.page
            end
            domain.page_langs.all.each do |lang|
                if lang.code.to_s == session[:current_locale].to_s && active_state_template
                  content = active_state_template.gsub('###LANG_CODE###', lang.code)
                              .gsub('###LANG_TITLE###', lang.title)

                elsif item_state_template.present?
                  content = item_state_template.gsub('###LANG_CODE###', lang.code)
                                .gsub('###LANG_TITLE###', lang.title)

                end
                if content
                  if page
                    content = content.gsub('###PAGE_LINK###', page.menu_url(session[:scheme], lang.code))
                  else
                    content = content.gsub('###PAGE_LINK###', '/')
                  end

                  subparts << content

                end
            end
          else
            attributes = item[:attributes]
            subparts.send(item[:name], attributes) do |next_subparts|
              self.language_generator(session, domain, item[:children], next_subparts, nil)
            end
        end

      end
    end


    def self.content_generator(session, domain, elements, subparts, hash_value)
      elements.each do |item|
        case item[:name]
          when 'text'
            subparts << self.replace_text_marker(subparts.parent.name, item[:source], hash_value)
          when 'repeat'
            repeat_id = item[:attributes]['id']
            @repeat_type_index[repeat_id] ||= 0
            scope = @page_content.page_content_markers.where(repeat_id: repeat_id)
            if hash_value && hash_value['PARENT_ITEM_ID'].present?
              scope = scope.where(parent_id: hash_value['PARENT_ITEM_ID'])
            end
            row_index = scope.pluck(:row_item).uniq.sort

            row_index.each_with_index do |row_index, position|
              value = scope.where(row_item: row_index).collect{|item| [item.marker, item.text_value] }.to_h

              if(position == 0)
                value['###FIRST_ITEM_ACTIVE###'] = 'active show'
                value['###FIRST_ITEM_TRUE###'] = 'true'
                value['###FIRST_ITEM_FALSE###'] = 'false'
              else
                value['###FIRST_ITEM_ACTIVE###'] = ''
                value['###FIRST_ITEM_TRUE###'] = 'false'
                value['###FIRST_ITEM_FALSE###'] = 'true'
              end
              value['###REPEAT_NUMBER###'] = "#{repeat_id}_#{row_index.to_s}_#{hash_value['PARENT_ITEM_ID'] || 0}"
              value['###REPEAT_CYCLE_COUNT###'] = @repeat_type_index[repeat_id].to_s
              value['PARENT_ITEM_ID'] = scope.where(row_item: row_index).first.uuid.to_s

              @repeat_type_index[repeat_id] += 1
              self.content_generator(session, domain, item[:children], subparts, value)

            end

          when 'language'
            code = item[:attributes]['code']
            if I18n.locale.to_s == code.to_s
              self.content_generator(session, domain, item[:children], subparts, hash_value)
            end
          when 'condition'
            condition_process = true

            if item[:name] == 'condition' && @page_content.present? && item[:attributes] && item[:attributes]['id']
              condition_process = hash_value[item[:attributes]['id']].to_i == 1 if item[:attributes]['type'].to_s.empty? || item[:attributes]['type'].to_s == 'enable'
              condition_process = hash_value[item[:attributes]['id']].to_i == 0 if item[:attributes]['type'].to_s == 'disable'
            end

            if condition_process
              self.content_generator(session, domain, item[:children], subparts, hash_value)
            end

          else
            attributes = self.replace_attributes_marker(item[:attributes], hash_value)
            if item[:name] == 'select'
              subparts.select(attributes) do |next_subparts|
                self.content_generator(session, domain, item[:children], next_subparts, hash_value)
              end
            elsif item[:name] == 'p'
              if item[:children].count > 0
                #subparts << "<p>#{self.replace_text_marker('p', item[:children][0][:source], hash_value).html_safe}</p>"
                subparts.p(attributes, self.replace_text_marker('p', item[:children][0][:source], hash_value).html_safe)
              end
            else
              subparts.send(item[:name], attributes) do |next_subparts|
                self.content_generator(session, domain, item[:children], next_subparts, hash_value)
              end
            end
        end

      end

    end

    def self.system_generator(session, domain, elements, subparts, hash_value)
      str = ''
      controller_item = elements.select{|item| item[:name] == 'controller' }.first
      action_item = elements.select{|item| item[:name] == 'action' }.first
      if controller_item and action_item
        controller_name_item = controller_item[:children].first
        action_name_item = action_item[:children].first
        if controller_name_item and action_name_item
          controller_name = controller_name_item[:source]
          action_name = action_name_item[:source]

          controller = controller_name.constantize.new
          controller.send action_name
          controller_variables = controller.instance_variables
          hash = {}
          controller_variables.each do |variable|
            hash[variable.to_s[1..-1]] = controller.instance_variable_get(variable.to_s)
          end
          str = controller_name.constantize.render action_name.to_sym, assigns: hash

        end

      end


      subparts << str
    end


    def self.replace_text_marker(parent_node_name, text, hash_value)
      new_text = text.dup

      if !hash_value.nil? and !text.nil?
        hash_value.each do |key, value|
          if !key.nil? and !value.nil?
            work_value = value.dup
            work_value.gsub!(/\r\n/, "#newline#") if !['code', 'pre'].include?(parent_node_name.to_s.downcase)
            new_text.gsub!(key, work_value.to_s.html_safe)
          end
        end
      end
      new_text
    end

    def self.replace_attributes_marker(attributes, hash_value)

      new_attributes = attributes.deep_dup
      if new_attributes.keys.include?('checked')
        new_attributes['make-checked'] = new_attributes.delete('checked')
      end

      attributes.each do |key, text|
        if !hash_value.nil? and !text.nil?
          hash_value.each do |key2, value2|
            if !key2.nil? and !value2.nil?
              key = 'make-checked' if key == 'checked'
              new_attributes[key].gsub!(key2, value2)
              new_attributes[key].gsub!('###FORM_ACTION###', "/#{I18n.locale}/form/#{@page_content_id}")
            end
          end
        end

      end
      new_attributes
    end





  end
end