Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

General

404 Only on first hit of a page

Started by Adrian Waterhouse 5 years ago · 10 replies · 530 views
5 years ago

Hello all,
I've a strange issue that seems to have developed but I'm not sure where from or what is causing it.

Basically after clearing cache the first hit to any page, including the homepage will return a 404 page.

Every subsequent call to the website the page will be displayed correctly.

Has anybody else had anything similar or have any tips as to what to look for, I've been looking at it for a while and tried disabling and reinstalling various plugins but nothing seems to make a difference.

Best,
Adrian

5 years ago

Hi @adrianw
Is this a live hosted) server or development server (local) that the problem is occuring.

Have you tried to run the site locally and see if the issue is happening.
Can you paste any log file errors (apache and grav (\logs\grav.log)

We might be able help diagnose a bit further from there , also if you can provide your current php and grav version for reference :)

5 years ago

hi @spamhater

Unfortunately there's no errors on any logs, it just jumps straight to the 404 on first hit after cache is cleared all latest version of Grav 1.7.16 plus plugins, Php running 7.3

It's happening on both live and local versions, it strangely seems to have something to do with a static function used to populate data-options@ for forms I'm just narrowing it down a little further.

5 years ago

maybe as quick fix is to turn the forms yaml and disable caching on that form,

TXT
cache_enable: false

possibility to also run the

BASH
 bin/grav yamllinter 

to see if that picks up any anomalies.

If you want to try and post the blueprint on here, feel free and we can try and recreate the issue

Otherwise process of elimination of the blueprint and see if you can find the point of error. Do feel free to go to the discord channel and drop the question there, if you are happy to share the blueprint and see if they can identify any issue :)

5 years ago

ok I've narrowed it down to a call, that I', wondering if calling it early that might upset something.

So I have really simplified the function that data-options@ is calling to just
$grav = Grav::instance();
$page = $grav['page'];
return[];

The simple act of $page = $grav['page'] seems to upset everything, I've noticed that the $page returned is the system notfound.md

Could it be that call $grav['page'] too early breaks the routing, or causes the a different page to be built?

I check yamlinter, no issues and forms are all cache disabled

last edited 06/08/21 by Adrian Waterhouse
5 years ago

what I've done is added

PHP
  $routes = $grav['pages']->routes();
  if(!$routes) {
    return null;
  }

to my original routine to check if routes have been setup, they aren't on the first call but are subsequently, before asking for the current page. That seems to have fixed it for me.

👍 1
5 years ago

Maybe because of the naming convention, with grav referring to pages and page as variables, it also worth staying clear of them as variable names just in case.

Old school programming
$page = ...
and go for
$mypage =
to keep things clear.

I am not the best on oops and getting my hands really dirty with the api

https://learn.getgrav.org/17/api

[s]but grav::instance seems to be deprecated and refers with a parameter for languages alot of the api refers to getInstance() instead.[/s]

This is sample of code from grav latest core

PHP
     /**
     * Return the Grav instance. Create it if it's not already instanced
     *
     * @param array $values
     * @return Grav
     */
    public static function instance(array $values = [])
    {
        if (null === self::$instance) {
            self::$instance = static::load($values);
        } elseif ($values) {
            $instance = self::$instance;
            foreach ($values as $key => $value) {
                $instance->offsetSet($key, $value);
            }
        }

        return self::$instance;
    }

I presume your blueprint is basically trying to display a list a of pages / all pages

It seems standard practice to check the parameter for existing data and then create the instance.

It is a big hard knowing only a snap shot of what your trying to do, but people like @pamtbaau will probably able to advise further , on best practises but I am sure he will require a bit more info (blueprint, function code etc, aim of functionality to be achieved)

last edited 06/08/21 by Spam Hater
5 years ago

@adrianw, I can reproduce your observation of a 404 error when cache has been cleared.

It is indeed caused by the call $page = $grav['page'].

When the page is being called after invalidating the cache, the static method for the form is being called before the pages are being initialized. When calling $page = $grav['page'] in the static method, there is no page yet known to Grav. That might somehow "confuse" Grav.

On subsequent calls, all pages have already been initialized.

I don't think the 404 should happen though. You might consider opening a call on Github.

👍 1
5 years ago

@pamtbaau I'm happy you were able to replicate it and it wasn;t just some quirk of my local system.

What I was trying to do is minimise the load of the dynamic options function, the forms have a large amount of dynamic data.

The system calls the static function multiple times on every page load regardless of it being a form or not which was quite a large overhead, so my thought was to check and allow the build to go ahead only if the page being displayed was a form.

5 years ago

@adrianw, Again, I can confirm your observation that the static method is being called on every page request, even if the page doesn't have a form...

This is not what I would expect and I've created an issue for the Form plugin.

As a workaround, try the following:

PHP
public static function myMethod()
{
    $grav = Grav::instance();
    $uri = $grav['uri'];
    $route = $uri->route();

    if ($route === 'expected-route') {
        // do useful things
        return 'useful data';
    }
}

In case you want to store the route(s) in the config file of the plugin use for example:

PHP
$routes = $grav['config']->get('plugins.yourplugin.routes', []);
last edited 06/09/21 by pamtbaau
5 years ago

Thanks @pamtbaau yes it came as a surprise to me too, thanks for the idea, unfortunately I can't go down the uri method as there's quite a number of different forms on different uri's and the client can create them without me being able to change the underlying code, hence my idea of checking if a page contained any forms.
I've found a workaround I can use for now which I showed above, which is to check if the pages routes have been setup before I check if the page has forms.

Thanks for your help in this matter.

Suggested topics

Topic Participants Replies Views Activity
General · by Jerry Hunt, 4 days ago
2 74 6 hours ago
General · by pamtbaau, 12 hours ago
1 47 11 hours ago
General · by Andy Miller, 24 hours ago
0 44 24 hours ago
General · by Marcel, 12 months ago
6 346 5 days ago
General · by Duc , 5 days ago
3 39 5 days ago