# Structure field hooks

**URL:** <https://forum.getkirby.com/t/structure-field-hooks/15733>\
**Category:** Questions\
**Tags:** v3\
**Created:** [September 20, 2019, 8:14pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733 "2019-09-20T20:14:28Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![diezmilseres](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/diezmilseres/32/6808_2.png) [@diezmilseres](https://forum.getkirby.com/u/diezmilseres)\
**Post date:** [September 20, 2019, 8:14pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/1 "2019-09-20T20:14:28Z")

</div>

hi and thanks for kirby,

i need to intercept structure field add and save actions. any ideas?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [September 20, 2019, 8:15pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/2 "2019-09-20T20:15:30Z")

</div>

Hm, could you please provide more information what you are trying to achieve?

---

<div class="post-metadata">

**Author:** ![diezmilseres](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/diezmilseres/32/6808_2.png) [@diezmilseres](https://forum.getkirby.com/u/diezmilseres)\
**Post date:** [September 20, 2019, 8:27pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/3 "2019-09-20T20:27:02Z")

</div>

hi,

for this project a need to generate an ID (or unique number) when the user add o save the structure field.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [September 20, 2019, 8:29pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/4 "2019-09-20T20:29:50Z")

</div>

You might want to check out the AutoID plugin: [https://github.com/bnomei/kirby3-autoid](https://github.com/bnomei/kirby3-autoid)

---

<div class="post-metadata">

**Author:** ![diezmilseres](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/diezmilseres/32/6808_2.png) [@diezmilseres](https://forum.getkirby.com/u/diezmilseres)\
**Post date:** [September 20, 2019, 8:50pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/5 "2019-09-20T20:50:59Z")

</div>

i already checked, but it only generate on “page save hook”, the problem is that i need to generate an ID like this format:

R-GLOBALCOUNTERNUMBER-ALEATORYNUMBER

R-345-AER  
R-346-RGF  
R-348-OGM

and so…

i tweaked de DEFAULT GENERATOR FUNCTION to read a site field with the counter number,.

if i only create 1 structure it works ok, but when i create 2 or more it create

R-345-AER  
R-345-RGF  
R-345-OGM

this is AUTOID modified code

```
  public static function getToken($length = 40, $withLower = true, $withUpper = true, $withNumbers = true)
    {
        $token = "";
        $codeAlphabet = "";
        $contador = site()->contador();

        $contador = site()->contador()->int() + 1;
        kirby()->impersonate('kirby');

        site()->update([
             'contador' => $contador,
        ]);

        if ($withUpper) {
            $codeAlphabet .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        }
        if ($withLower) {
            $codeAlphabet .= "abcdefghijklmnopqrstuvwxyz";
        }
        if ($withNumbers) {
            $codeAlphabet .= "0123456789";
        }

        $token .= $contador . "-";

        $max = strlen($codeAlphabet); // edited
        for ($i=0; $i < $length; $i++) {
            $token .= $codeAlphabet[self::cryptoRandSecure(0, $max-1)];
        }
        return $token;
    }
```

---

<div class="post-metadata">

**Author:** ![bnomei](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bnomei/32/775_2.png) [@bnomei](https://forum.getkirby.com/u/bnomei)\
**Post date:** [September 21, 2019, 7:20am UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/6 "2019-09-21T07:20:39Z")

</div>

you can search for “auto incrementing id” in the forum and find different solutions how to set it up with autoid. it usually involves storing a global counter at the site object (site.yml blueprint). this will work fine unless you have many concurrent ids being created (like 20 per second).

1. call $site-\>increment(‘myincrementid’) to prepare new value. [https://getkirby.com/docs/reference/objects/site/increment](https://getkirby.com/docs/reference/objects/site/increment)
2. read $site-\>myincrementid()-\>toInt()

---

<div class="post-metadata">

**Author:** ![bnomei](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bnomei/32/775_2.png) [@bnomei](https://forum.getkirby.com/u/bnomei)\
**Post date:** [September 21, 2019, 7:26am UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/7 "2019-09-21T07:26:11Z")

</div>

on a side note: if you override autoid core logic you will lock yourself out of updates. consider using the generator callback which you can set in the config to provide your own. it can reuse the getToken function to generate parts if your string.

> [@How to create unique number for each new post?](https://forum.getkirby.com/t/how-to-create-unique-number-for-each-new-post/15628/12):
>
> like @texnixe said. if you overwrite the generator option you should be fine. you can cut some corners and get asimple hash fast if you use the getToken with different params

---

<div class="post-metadata">

**Author:** ![diezmilseres](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/diezmilseres/32/6808_2.png) [@diezmilseres](https://forum.getkirby.com/u/diezmilseres)\
**Post date:** [September 21, 2019, 3:57pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/8 "2019-09-21T15:57:58Z")

</div>

thanks for the answer.

for test purposes :

new function on kirby3-autoid/classes/AUTOID.php

```
public static function testGenerator(): string
    {
        $contador = "";
        $token = "";

        $contador = site()->increment('contador');

        $con = site()->contador()->int();

        $token .= "R-" . $con;

        return $token;
    }

```

replace on kirby3-autoid/index.php

```
'generator' => function (string $seed = null) {

          return \Bnomei\AutoID::testGenerator();
        },

```

result 1: when i only generate 1 structure and save. **the counter works good, it add 1.**  
result 2: when i generate 2 or more structures and save. **the counter only add 1 and the counter repeat**

 ![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/9/96e441a26f73df3bc8b29f8f41c070e1abf9d138.png)

sure i am missing something. my expected result is that the client can generate 2 or more invoices and on page save the invoices have consecutives numbers.

---

<div class="post-metadata">

**Author:** ![bnomei](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bnomei/32/775_2.png) [@bnomei](https://forum.getkirby.com/u/bnomei)\
**Post date:** [September 21, 2019, 9:39pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/9 "2019-09-21T21:39:02Z")

</div>

extending the autoid class will reset if you update the plugin.  
to avoid that please put everything from testGenerator() into the generator callback.

you are not missing something. there is no api call, no hook for adding structure item. a structure is just a special field. it gets updated on parent object save. the structure is not a “first order” cms object like the page or a file.

my suggestion would be: to get what you want you need to change the structure to a pages section and add pages for each invoice. the info option of the section field can be forwarded html code. you could use a page model/method to create a nice summary of the invoice this way.

edited: you will have to exclude the invoices from sitemap/feeds and protect them from access (for example: make their template redirect to parent objects url).

---

<div class="post-metadata">

**Author:** ![diezmilseres](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/diezmilseres/32/6808_2.png) [@diezmilseres](https://forum.getkirby.com/u/diezmilseres)\
**Post date:** [September 21, 2019, 9:54pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/10 "2019-09-21T21:54:57Z")

</div>

hi and thanks for the answer,

What I do not understand, is that with the “default generator” when I create 2 or more structures this generates two unique id

but with “test generator” no, I don’t understand how it doesn’t trigger site-\> update () twice

Will there be any way to add a consecutive counter?

---

<div class="post-metadata">

**Author:** ![bnomei](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bnomei/32/775_2.png) [@bnomei](https://forum.getkirby.com/u/bnomei)\
**Post date:** [September 22, 2019, 9:32pm UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/11 "2019-09-22T21:32:04Z")

</div>

adding two or more items to a structure results in only one page update hook.  
maybe incrementing a field in site index twice within the one page update call does not work. i have no time to check this myself. maybe @texnixe can help you with that or ask someone in the thread linked above.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [September 24, 2019, 9:16am UTC](https://forum.getkirby.com/t/structure-field-hooks/15733/12 "2019-09-24T09:16:10Z")

</div>

I actually think in this case maybe a custom solution would be better, with an internal counter that reads the site value only once and updates it when all items have their unique ID applied.

However, I see a general problem with this approach when using multiple structure fields that all update the site value. So knowing a bit more about your use case would be helpful.
