TomG
TomG

Reputation: 81

Render dynamic content in a CMS page

I have to render dynamic content (search result of offers) in an Alchemy CMS page.

First I made, in the cms-backend, a page called "searchresult".

I made an element without essences. A table should be rendered.

The seachform has as action /searchresult and the page is called with the (get)-search params:

/searchresult?utf8=✓&searchmaingroup=bb&searchprofgroup=4100

But where can I collect the data for this?

I tried a page_layout with the configuration option "controller" and "action" to an own controller

- name: offersearch
  elements: [header, resulttable]
  autogenerate: [header, resulttable]
  controller: offers
  action: index
  cache: false

Controller:

OffersController < Alchemy::BaseController
  def index

  end
end

But this makes still a redirect to this controller and the searchparams are lost.

Is there any "hook" in Alchemy cms where I can catch the searchparams and fill a variable like:

@offers = Offer.where(...)

and take this to the cms page element (view-partial)

I tried to find a solution here: Creating a custom Guestbook Module for Alchemy CMS

But this is unfortunately not complete enough for me. (The custom offer-module in my CMS backend works fine.)

Upvotes: 2

Views: 1315

Answers (2)

Robin
Robin

Reputation: 915

As a side note: Did you see the alchemy-ferret gem? (In older Alchemy versions its a build in feature) Its searches all your EssenceText and EssenceRichtext (if you dont switch it off for certain essences), but maybe its worth a look.

I prefer to not rely on page url names like you did by setting the name in the routes - because other content editors could easily rename that page, or create one in a different language tree with a wrong name.

Instead I would define a page_layout that is used for the search results only.

# config/alchemy/page_layouts.yml
- name: searchresults
  elements: [offer_searchresults]
  unique: true
  cache: false

Then you can extend the existing Alchemy::Page class with your search handling method:

# app/controllers/alchemy/pages_controller_ext.rb
module Alchemy
  PagesController.class_eval do

    before_filter :set_searchresult_page, :only => :show
    before_filter :perform_search, :only => :show

    def perform_search
      if params[:searchprofgroup].present? && @search_result_page
        @offers = Offer.where(fb: params[:searchprofgroup])
      end
    end

   private

   def set_searchresult_page
     @search_result_page = Page.published.where(page_layout: "searchresults").first
   end

  end
end

And the last thing you have to do is to tell Rails that these extension should be used

# config/application.rb
config.to_prepare do
  Dir.glob(Rails.root.join("app/**/*_ext*.rb")) do |c|
    Rails.configuration.cache_classes ? require(c) : load(c)
  end
end

Upvotes: 2

TomG
TomG

Reputation: 81

Here is my own solution.

Don't know, if this is the right way - but it works :-)

Sat a route for the pagename to the controller#action:

  get '/searchresult' => 'offers#handlesearch', :as => :searchresult

Controller:

The Controller inherits from Alchemy::PagesController and uses the Alchemy::PagesHelper

Then sat the params[:urlname] to requested path. So the Controller can load the correct page description. The rest is handled by the Alchemy magic.

class OffersController < Alchemy::PagesController

  helper Alchemy::PagesHelper

  def handlesearch

    params[:urlname] = request.path_info.gsub('/', '')
    @page ||= load_page

    if [email protected]?
      @offers = Offer.where(fb: params[:searchprofgroup])
    else
      render_404
    end

  end

end

and finally the view:

#/app/views/offers/handlesearch.html.erb
<%= render_page_layout %>

thats it

Upvotes: 0

Related Questions