Forum

Thread tagged as: Problem, Error, Field-Types

Custom map fieldtype adding page resources multiple times

Hi,

I've copied your original map field and changed it a little bit to add a few extra options, like outputting the "addr" field only (and not the map itself) all within a template. Your docs for a custom fieldtype says that the add_page_resources() function is only included once per page, but the google maps api script is being included twice in the admin panel, which I think is causing the assets JS to malfunction as I don't seem to be able to upload any assets when I have my field type active in the template. I'm using Perch Runway.

I'm looking at the PerchFieldTypes.class.php file and it seems to only add classes to the $_seen array if they are already included and so the add_page_resources() function gets called twice for my custom fieldtype.

You can see the full code for the PerchFieldType_gmap.class.php here - https://pastebin.com/5jFyxNeu

My template is here: https://pastebin.com/pcDWvTjd

My diagnostic report here: https://pastebin.com/enZrCFmN

Oliver Lowe

Oliver Lowe 0 points

  • 4 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

Are you sure it's getting called twice? I can't reproduce that.

Could you try turning on debug and adding this to your add_page_resources() method?

PerchUtil::mark('add_page_resources: gmap');

You should then see a big blue bar in the debug every time it gets called.

I'm sure it's getting called twice, yes. Your snippet confirmed:

0.0374  0.0048  ------------------------------ add_page_resources: gmap ------------------------------
0.0376  0.0001  ------------------------------ add_page_resources: gmap ------------------------------

Also I'm getting google errors in the console:

You have included the Google Maps API multiple times on this page. This may cause unexpected errors.
js?key=...:102 
bh @ js?key=...:102
Drew McLellan

Drew McLellan 2638 points
Perch Support

Do you get any insight if you hover over those?

gmap.class.php: PerchFieldType_gmap->add_page_resources(): is the only insight.

It's odd that you can't reproduce. Is the PerchfieldTypes::get method behaving as expected, only adding a class to the $_seen array after it's been included? That's where the problem seems to be, or at least where I've narrowed it down to possibly occurring!

Drew McLellan

Drew McLellan 2638 points
Perch Support

Yes, that's the only way the add_page_resources() method gets invoked.

Yes absolutely. I guess I would expect to see the class added to the $_seen array after you call add_page_resources() inside the else{} clause. See below.

if (class_exists($classname, false)){
    $r = new $classname($Form, $Tag, $app_id);
    if (!in_array($classname, self::$_seen)) {
        $Perch = Perch::fetch();
        if ($Perch->admin) {
            if (count($all_tags)) $r->set_sibling_tags($all_tags);
            $r->add_page_resources();
        }

        self::$_seen[] = $classname;
    }

}else{
    $path = PerchUtil::file_path(PERCH_PATH.'/addons/fieldtypes/'.$type.'/'.$type.'.class.php');
    if (file_exists($path)) {
        include($path);
        $r =  new $classname($Form, $Tag, $app_id);

        $Perch = Perch::fetch();
        if ($Perch->admin) {
            if (count($all_tags)) $r->set_sibling_tags($all_tags);
            $r->add_page_resources();
        }

        // I'd expect to see something like this?
        self::$_seen[] = $classname;
    }
}

I've actually just created a super basic test fieldtype and it's adding TESTING_CONTENT to the footer twice here too!

<perch:content type="test" id="test" />

Inside perch/addons/fieldtypes/test/test.class.php

<?php

class PerchFieldType_test extends PerchFieldType
{
    public function add_page_resources()
    {
        $Perch = Perch::fetch();
        $Perch->add_foot_content('TESTING_CONTENT');
    }
}

It might be worth adding that I'm using this template inside a collection?

Drew McLellan

Drew McLellan 2638 points
Perch Support

I think you're probably spot on there - we should be adding to $_seen when the class is first included.

Add your expected self::$_seen[] = $classname; and I'll do the same here for the next update.

Ok, great. Will Do.

Thanks Drew