anchor.diff:              []
       end;
   
  -parse_argument({cat_exclude_defaults, Val}) ->
  -    parse_argument({cat_exclude_defaults, z_convert:to_bool(Val)});
  +parse_argument({cat_exclude_defaults, Val}, Context) ->
  +    parse_argument({cat_exclude_defaults, z_convert:to_bool(Val)}, Context);
  +
  +parse_argument({cat_exclude_unfindable, Val}, Context) ->
  +    case z_convert:to_bool(Val) of
  +        true ->
  +            [{cat_exclude, get_unfindable_categories(Context)}];
  +        false ->
  +            []
  +    end;
   
   % Filtering on undefined is supported from Zotonic 0.13.16
  -parse_argument({has_geo, true}) ->
  +parse_argument({has_geo, true}, _Context) ->
       [{filter, ["pivot_location_lat", ne, undefined]},
        {filter, ["pivot_location_lng", ne, undefined]}];
  -    
  -parse_argument({has_geo, false}) ->
  +
  +parse_argument({has_geo, false}, _Context) ->
       [{filter, ["pivot_location_lat", eq, undefined]},
        {filter, ["pivot_location_lng", eq, undefined]}];
  -    
  -parse_argument({has_geo, Val}) ->
  -    parse_argument({has_geo, z_convert:to_bool(Val)});    
   
  -parse_argument({_, undefined}) ->
  +parse_argument({has_geo, Val}, Context) ->
  +    parse_argument({has_geo, z_convert:to_bool(Val)}, Context);
  +
  +parse_argument({_, undefined}, _Context) ->
       [];
  -    
  -parse_argument({Key, <<"undefined">>}) ->
  -    parse_argument({Key, undefined});
   
  -parse_argument(Arg) ->
  +parse_argument({Key, <<"undefined">>}, Context) ->
  +    parse_argument({Key, undefined}, Context);
  +
  +parse_argument(Arg, _Context) ->
       [Arg].
  -    
  +
   %% @doc Process custom arguments and add defaults
  -merge_ginger_args(Args) ->
  -    
  +merge_ginger_args(Args, Context) ->
  +
       % Always set these extra query arguments
       ExtraArgs = [
  -        {custompivot, "ginger_search"}
  +        {custompivot, ?GINGER_SEARCH_PIVOT}
       ],
       MergedArgs = lists:merge(ExtraArgs, Args),
   
  
positive.code:     DefaultArgs = [
          {is_findable, true},
          {is_published, true},
          {cat_exclude_defaults, true}
      ],
      MergedArgs1 = withdefault(DefaultArgs, MergedArgs),
  
      % Parse custom ginger_search arguments
      lists:flatmap(fun parse_argument/1, MergedArgs1).
      
  %% @doc Supports all the usual query model arguments, adds default excludes.
  search_query(#search_query{search={ginger_search, Args}}, Context) ->
      QueryArgs = merge_ginger_args(Args),
      search_query:search(QueryArgs, Context).
  
negative.code: -module(ginger_search).
  
  -export([
      search_query/2,
      get_unfindable_categories/1,
      merge_ginger_args/2
  ]).
  
  -include_lib("zotonic.hrl").
  
  -define(GINGER_SEARCH_PIVOT, ginger_search).
  
  %% @doc Supports all the usual query model arguments, adds default excludes.
  search_query(#search_query{search={ginger_search, Args}}, Context) ->
      QueryArgs = merge_ginger_args(Args, Context),
      search_query:search(QueryArgs, Context).
  
  %% @doc Get categories marked unfindable that must be excluded from search results
  -spec get_unfindable_categories(#context{}) -> list().
  get_unfindable_categories(Context) ->
      Categories = z_search:query_(
          [
              {cat, category},
              {custompivot, ?GINGER_SEARCH_PIVOT},
              {filter, ["is_unfindable", true]}
          ],
          Context
      ),
      lists:map(
          fun(Category) ->
              m_rsc:p(Category, name, Context)
          end,
          Categories
      ).
  
  %% @doc Add property to proplist if not defined
  withdefault({Key, _} = Prop, Proplist) ->
  