I have three (3) different channels. One (1) channel have Assets attached to it, and those Assets have a couple of fields attached to them as well.

How can I make the broadest possible search on all these channels (and the channels Assets and fields) using the .search() function?

For clarification; I want to make a search in all channels, and their Assets (and the Assets own fields) with (if possible) one single line of code.

  • Hey there! What do you mean by the "channel have Assets attached to it?" Are there just entries inside that channel that have assets? – Aaron Berkowitz Feb 2 '15 at 14:29
  • The channel has a "Asset" field type attached to it. The added assets (through this field) have their own fields as well. Thanks. – naboovalley Feb 2 '15 at 15:02
  • Ok cool. What are you hoping to return? Entries, assets, or both? – Aaron Berkowitz Feb 2 '15 at 15:14
  • I would like to return entries, but the search would include the searching through the fields for the added assets as well. It not possible I guess I can always run a search() on both entries and assets and combine the result in the template. But would like to avoid it if possible :) – naboovalley Feb 2 '15 at 15:18

I gave this a quick test, and it seems that Craft only searches the title field of related assets, when searching entries. What you could do, is first search for all entries with your search term, then all assets with the search term AND related to an entry. Combine those to sets of ids, and you're all set (not really one line of code, though):

{# your search term #}
{% set searchTerm = craft.request.param('q') %}

{# first, search all entries with given search term #}
{% set entries = craft.entries.search(searchTerm).ids() %}

{# first, search all assets with given search term and their relations #}
{% set assets = craft.assets.search(searchTerm).ids() %}
{% set entriesRelatedToAssets = craft.entries.relatedTo(assets).ids() %}

{# Combine those ids to one array #}
{% set allIds = entries | merge(entriesRelatedToAssets) %}

{# Then get all the entries with the given IDs #}
{% for entry in craft.entries.id(allIds) %}
    {{ entry.title }}<br />
{% endfor %}
  • This is the idea I had which is totally okay. I guess what I'm trying to do can't really be done with one line of code? Thanks for the code sample! – naboovalley Feb 2 '15 at 15:20
  • Someone MIGHT know some search() tricks to also search custom fields in related elements. Then it could be done with one line of code. Maybe an email to P&T could give some clarity. – Paul Feb 2 '15 at 15:22
  • How do you think this code will behave/perform when searching through let's say 100,000 entries? Template overload? :P – naboovalley Feb 2 '15 at 15:37
  • Don't know. Using .ids() is better (performance-wise) than getting all the objects, but you'd have to test it to be sure. – Paul Feb 2 '15 at 15:39

Your Answer

