Giter Club home page Giter Club logo

Comments (6)

Sebb767 avatar Sebb767 commented on June 3, 2024

Hey,

I'm currently looking into this, this might be an API bug. Just so I get this right, you have the following behavior:

  • Query with slug = /home and locale = en-US-> returns the correct entry
  • Query with slug = us/home and locale = en-US-> returns the correct entry
  • Query with slug = ca/home and locale = en-CA-> returns the correct entry
  • Query with slug = us/home and locale = en-CA-> returns nothing, should return same entry

Am I getting this right?

from contentful.php.

Sebb767 avatar Sebb767 commented on June 3, 2024

After some further clarification, the problem seems to be the following: Given a field with a localized value, a query to the field will not search values in different locales. If you don't give a locale or *, the API will use the default locale and not search other locales, either. This seems to be a limitation of the API at the moment.

You can do any the following to work around this limitation:

  1. Use fulltext search. In this case, instead of $this->query->where('query', $slug), you would use $this->query->where('fields.slug', $slug); . This will search all locales and find results as expected, but will do a full word search on all fields - so it might return more or different results than anticipated (for example, if a text contains this link, it will be found, too). Therefore, it's necessary to filter the results again on the client side in order to extract the correct locale and verify whether it's an actual match.
  2. If it's possible to extract the locale from the slug (like in the ca/home example), directly query the field in the correct locale.
  3. Another option is to cache a map of localized slug to slug and use this lookup to query the correct entry with locale * to get all fields.
  4. Lastly, if everything else does not fit, you will need to query in all locales. I'd advice against this, since you will use the API a lot and slow down your page.

from contentful.php.

annikaC avatar annikaC commented on June 3, 2024

Thanks for looking into this @Sebb767 - is the fix for supplying '*' to the query in the API roadmap at all and is there a booked timeline to fix that you could share with us?

The workarounds for this are not ideal - like you said, 1. would fetch everything where the slug is mentioned, and 2. doesn't work for dynamic localised content on the same slug, so 3 is looking like the only option at the moment.

from contentful.php.

Sebb767 avatar Sebb767 commented on June 3, 2024

Hi @annikaC ,

Thanks for looking into this @Sebb767 - is the fix for supplying '*' to the query in the API roadmap at all and is there a booked timeline to fix that you could share with us?

Unfortunately, there is no timeline yet and I don't know whether they plan on changing it - I'm currently in contact with the API team, I will update you once I know more.

The workarounds for this are not ideal - like you said, 1. would fetch everything where the slug is mentioned, and 2. doesn't work for dynamic localised content on the same slug, so 3 is looking like the only option at the moment.

If you want, I can provide you example code for option 1 - it's probably a lot easier than maintaining a cache.

from contentful.php.

annikaC avatar annikaC commented on June 3, 2024

That would be fantastic, @Sebb767 - thank you!

from contentful.php.

Sebb767 avatar Sebb767 commented on June 3, 2024

Hi @annikaC ,

you can use the following function:

function QuerySlugInAllLocales(string $searchedSlug, \Contentful\Delivery\Query $query, \Contentful\Delivery\Client $client) : array {
    // first, we make a general query with the slug as keyword
    $query->where('query', $searchedSlug);
    // it's important to set the locale to * in order to fetch the entries with all available locales
    $query->setLocale('*');
    // next, query the entries
    $entries = $client->getEntries($query);

    // Since we did a full text search, the results might contain extra entries we weren't looking for and the locale
    // won't be set correctly. Therefore, we need to do a second run filtering the query results. For this, we iterate
    // over all returned entries.
    $results = [];
    foreach ($entries as $entry) {
        // ... and all of their locales.
        foreach ($entry->getEnvironment()->getLocales() as $locale) {
            $localeCode = $locale->getCode();
            $entrySlug = $entry->get('slug', $localeCode);

            // If the slug in the current locale exactly matches our search, we have an exact match
            if ($entrySlug === $searchedSlug) {
                // If we have a match, we set the correct locale for the entry and add it to our results.
                $entry->setLocale($localeCode);
                $results[] = $entry;
                break;
            }
        }
    }
    return $results;
}

Integrating it into the code @sebalaini-itm posted above, it would look like this:

const PAGE_CONTENT_TYPE = 'page';
const ENTRY_LIMIT       = 1;
const INCLUDES          = 8;
....

$slug = $this->slug === '/' ? $this->slug : trim($this->slug, '/');
$this->query->setLimit(self::ENTRY_LIMIT);
$this->query->setContentType(self::PAGE_CONTENT_TYPE);
$this->query->setInclude(self::INCLUDES);
// skip setting the slug filter and the locale here and call the function instead of the client
$entries = QuerySlugInAllLocales($slug, $this->query, $this->client);
dd($entries);

Hope this helps!

from contentful.php.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.