manastech / middleman-search

LunrJS-based search for Middleman
MIT License
58 stars 31 forks source link

Access Dynamic Page Variables #28

Closed macandcheese closed 6 years ago

macandcheese commented 7 years ago

Hi - looking for a solution for the following use case.

I have a bunch of dynamic pages set up, and have pointed the config to index them by directory. This works fine! However, I am having trouble returning data from these templates in the results.

I dynamically set the page title AFTER the frontmatter, using the meta tags gem. However, as defined in config.rb:

    search.fields = {
      title:   {boost: 100, store: true, required: true},
      type: { boost: 50, store: true},
      content: {boost: 50},
      url:     {index: false, store: true},
      author:  {boost: 30}
    }

that is scraping the title from frontmatter, which upon build I am overriding in the template below. However, if I want to display the page title in the results dropdown, I would need to access updated page title vs. the fallback defined in frontmatter. So I currently have:

var content = item.noresults
? '<span class="noresults">No results found</span>'
: '<a href="' + item.url + '">' + item.title + '<span class="search-result-type">' + item.type +'</span>' + '</a>';
$(this.menu.element).toggleClass('noresults', item.noresults);
return $("<li>").append(content).appendTo(ul);
};

but what I really want is:

var content = item.noresults
? '<span class="noresults">No results found</span>'
: '<a href="' + item.url + '">' + **page title as defined in template AFTER metadata** + '<span class="search-result-type">' + item.type +'</span>' + '</a>';
$(this.menu.element).toggleClass('noresults', item.noresults);
return $("<li>").append(content).appendTo(ul);
};

So - to the question. Is there a way to evaluate page-level dynamic data, or, short of that, evaluate "title" from the template vs. frontmatter? I've tried removing from frontmatter and that fails to index anything at all, even though it's later defined in the template.

Thanks!

joshRpowell commented 7 years ago

@macandcheese any progress on this? i'm running into the same issue.

macandcheese commented 7 years ago

@joshRpowell sorry for the delay, just seeing this.

No, I was not able to get middleman-search to interpret item.title set outside of Frontmatter.

Unfortunately it seems like it scrapes the frontmatter only and won't interpret any overrides specified afterwards in the template. Since I was trying to display the name of the article in the results, I think I did something like create a function to clean the item.url (remove "-", capitalize letters), and then reference that cleaned title in the results dropdown template to re-create the desired item.title.

Certainly not an ideal solution... this seems like a common use case to want to reference a dynamically-set Middleman attribute like item.title.

macandcheese commented 6 years ago

To follow up, this was solved by https://github.com/manastech/middleman-search/issues/35 - I was having trouble passing the entirety of an item's data PLUS an additional custom field to be indexed, but the below solved it. The syntax is slightly different than in the above thread but this worked in my case. In config.rb for dynamically generating a page:

if File.exist?("data/blog/categories.yml")
  data.blog.categories.items.each do |item|
    p = item
    proxy "blog/category/#{p.slug}", "blog/category/template.html", locals: { item: p, :searchtitle => p.title  }, ignore: true
  end
end

Then in the activate block I use the manual manipulation example from the docs homepage.

Then in your search.js or equivalent you can just reference item.searchtitle. Brilliant!