Skip to content

Instantly share code, notes, and snippets.

@joaogarin
Last active June 29, 2019 14:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joaogarin/c1aba92b91634806ea7913f5038c83fa to your computer and use it in GitHub Desktop.
Save joaogarin/c1aba92b91634806ea7913f5038c83fa to your computer and use it in GitHub Desktop.
Technical proposal : Job Search Facet SEO

We would essentially treat each occupation & region as a “category” of a job search. Inside category all other filters would be excluded. That would mean that in the front-end we have a route like /jobs/:arg1/:arg2

Meaning that we basically need to ask drupal what our arg1 and arg2 are. So when getting something like /manager/wien we call Drupal with this and drupal will respond like :

[
  "arg1" : "occupation"
  "arg2" : "region"
]

Asking drupal is important because we can get /manager/wien but we can also get only /manager or /wien and also /manager/wien?other_field=value or /manager?region=austria&region=switzerland

Currently we pass the filters to the jobs GraphQL query (jobQuery) and in this case we can extend it to receive these parameters as well so that the end result conditions are dealed with in the API where we can easily access Drupal's Term system (taxonomy). This would then most likely be a data producer that we can chain with the existing one.

We currently call the query with conditions that come directly from the frontend (via Apollo variables in GraphQL queries) like this :

<Query {JOB_SEARCH} variables={
  ...
  condition_group: [
    {
      name: 'occupation'
      value: 272
      operator: EQUAL
    },
    {
      name: 'region'
      value: 1726
      operator: EQUAL
    }
  ]
...
}/>

Since now in the case of a URL such as /jobs/manager/wien we dont know in advance the term id's or even which vocabularies which means we need to ask Drupal so we would transform this query so that we can send optional "query_arguments" (query arguments) that will be transformed into conditions by the API directly.

...
query_arguments: [
  {
    arg: 1,
    value: 'manager'
  },
  {
    arg: 2,
    value: 'wien'
  }
],
condition_group: [
  {
    name: 'company'
    value: 272
    operator: EQUAL
  }
]
...

We introduce a new API data producer called term_resolve that we can chain with the existing SearchAPI query. This data producer will transform the arguments that it receives (arg1 = manager & arg2 = wien) into "normal" conditions that the SearchAPI expects with the appropriate term ids and vocabulary names.

The API would look like this :

$registry->addFieldResolver('Query', 'jobs',
  $builder->compose(
    $builder->produce('term_resolve', [
      'arg1' => $builder->fromArgument('arg1'),
      'arg1' => $builder->fromArgument('arg1'),
      'condition_group' => $builder->fromArgument('condition_group'),
    ]),
    $builder->produce('search_api_load', [
      'mapping' => [
        'index_id' => $builder->fromValue('job_search'),
        'language' => $builder->fromArgument('language'),
        'facets' => $builder->fromArgument('facets'),
        'condition_group' => $builder->fromParent(), // This will be resolved by the previous producer.
        'range' => $builder->fromArgument('ranges'),
        'sort' => $builder->fromArgument('sorts'),
        'fulltext' => $builder->fromArgument('fulltext'),
      ],
    ])
  )
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment