# Trouble with creating a variable Attribute for a #person using functions

**URL:** https://community.silverbullet.md/t/trouble-with-creating-a-variable-attribute-for-a-person-using-functions/1563
**Category:** v1: Troubleshooting (legacy)
**Created:** [December 31, 2024, 2:06pm UTC](https://community.silverbullet.md/t/trouble-with-creating-a-variable-attribute-for-a-person-using-functions/1563 "2024-12-31T14:06:14Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Mr.Red](https://community.silverbullet.md/user_avatar/community.silverbullet.md/mr.red/32/821_2.png) [@Mr.Red](https://community.silverbullet.md/u/Mr.Red)
#### Post date: [December 31, 2024, 2:06pm UTC](https://community.silverbullet.md/t/trouble-with-creating-a-variable-attribute-for-a-person-using-functions/1563/1 "2024-12-31T14:06:14Z")

</div>

I cant seem to figure it out myself.

I want to make a list with birthdays of people and want to sort it based on the calculated days until the next Birthday, similar to this:

| Name | Birthday | Age | Next Birthday (sort asc) |
| --- | --- | --- | --- |
| John | 1984-01-01 | 41 | 1 days |
| Mary | 2000-02-14 | 24 | 45 days |
| Peter | 1986-05-01 | 38 | 121 days |
| … | … | … | … |

I have the names and birthday attributes in a #person codeblock and i also have the scripts to `CalculateAge` and `DaysUntilNextBirthday` which then I added to the template to create the list.  
Until now everything is fine. But what i have trouble with is to sort the list based on the next birthday. because it’s not an active attribute but rather a caculated value in the table template.

```auto
name: Mary
birthday: 2000-02-14 
---
name: Peter
birthday: 1986-05-06 
---
name: John
birthday: 1996-06-13
---
name: Anna
birthday: 1991-12-17
---
name: Jim
birthday: 1983-09-28
---
name: Susan
birthday: 1987-07-10

```

The space-script to calculate the Age and DaysUntilNextBDay:

```space-scipt
silverbullet.registerFunction("daysTillBirthday",(date) => {
  const birthDate = Temporal.PlainDate.from(date)
  const now = Temporal.Now.plainDateISO();
  const thisYearBirthday = new Temporal.PlainDate(now.year, birthDate.month, birthDate.day);

  if (now.equals(thisYearBirthday)) {
        return 0; // Happy Birthday!
  } else if (Temporal.PlainDate.compare(now,thisYearBirthday) < 0) {
        // Birthday is still coming this year
        return now.until(thisYearBirthday, { largestUnit: 'days' }).days;
    } else {
        // Birthday has passed for this year, calculate for next year
        const nextYearBirthday = new Temporal.PlainDate(now.year + 1, birthDate.month, birthDate.day);
        return now.until(nextYearBirthday, { largestUnit: 'days' }).days;
    }
})

export function calcAge(birthday) {
  const birthDate = new Date(birthday);
  const today = new Date();
  let age = today.getFullYear() - birthDate.getFullYear();
  const monthDiff = today.getMonth() - birthDate.getMonth();
  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
    age--;
  }
  return age;
}

```

The list-template saved in “Library/Personal/Templates/BirthdayTable”:

```auto
---
tags: template
displayName: "Birthdays Table Template"
description: "Template to output the Birthday Table"
---
| [[{{name}}]] |{{niceDate(birthday)}} | {{dateDiff(niceDate(birthday), today(),"years")}}| {{daysTillBirthday(niceDate(birthday))}}|

```

and at last the Template for the list:

```auto
| Person | Birthday | Age | Days |
|--------|----------|-----|------|
{{{person where page = "birthdays_test" render [[Library/Personal/Templates/BirthdayTable]] order by "Days" asc}}}

```

what i get is a nice liste, exactly as i wanted but it’s not sorted in any way:

 ![image](https://community.silverbullet.md/uploads/default/original/1X/9359bb126f46d9f42f4709aa824b1ad2edbe5949.png)

If i sort by `birthday` or `name` it works without issues, because these are the initial attributes from the query. but when I try to sort after `"Days"` or `"Age"` it doesnt work, probably because these are calculated through the template, and are not attributes of the `person`.

I cant figure it out myself how to create a variable attribute and assign it to that person.  
I tried to assign using a @nextbd variable and declaring it wiht `#let`, but it’s not working:

```auto
name: Susan
birthday: 1987-07-10
nextbirthday: {{nextbd}}

```

```auto
{{#let @nextbd = daysTillBirthday(niceDate(@person.birthday))}}
{{/let}}

```

 ![image](https://community.silverbullet.md/uploads/default/original/1X/d0a724743d0de7d70b22d1cc3f991fe824201c7b.png)

i’m sure it’s somthing wrong with the syntax or something else. Could someone please help me with this one? Been trying for the last couple of hours, but nothing seems to work. i’m sure missing something…

Thanks in advance.

---

<div class="post-metadata">

### Author: ![Mr.Red](https://community.silverbullet.md/user_avatar/community.silverbullet.md/mr.red/32/821_2.png) [@Mr.Red](https://community.silverbullet.md/u/Mr.Red)
#### Post date: [December 31, 2024, 6:32pm UTC](https://community.silverbullet.md/t/trouble-with-creating-a-variable-attribute-for-a-person-using-functions/1563/2 "2024-12-31T18:32:58Z")

</div>

I kinda found a workaround which works, but I’m sure there must be a more elegant solution, and this doesn’t answer my question on how to add a variable attribute to a `person` depending on an existing attribute like `birthday`:

> My Workaround:  
> I ordered the table by _**daysTillBirthday(niceDate(birthday))**_

```auto
| Person | Birthday | Age | Days |
|--------|----------|-----|------|
{{{person where page = "birthdays_test" render [[Library/Personal/Templates/BirthdayTable]] order by daysTillBirthday(niceDate(birthday)) asc}}}

```

 ![image](https://community.silverbullet.md/uploads/default/original/1X/ea48f96d058cc0caab03fe5b84d6a8323e7325e0.png)

---

<div class="post-metadata">

### Author: ![22rw](https://community.silverbullet.md/user_avatar/community.silverbullet.md/22rw/32/659_2.png) [@22rw](https://community.silverbullet.md/u/22rw)
#### Post date: [January 30, 2025, 11:57am UTC](https://community.silverbullet.md/t/trouble-with-creating-a-variable-attribute-for-a-person-using-functions/1563/3 "2025-01-30T11:57:27Z")

</div>

Sounds like [Object Decorators](https://silverbullet.md/Object%20Decorators) would make this a bit cleaner. The example on the page pretty much already does what you want, but, without testing it, my approach would look something like this:

```yaml
objectDecorators:
- where: 'tag = "person"'
  attributes:
    daysTillBirthday: 'daysTillBirthday(niceDate(birthday))'

```

Which would let you sort your query by the “daysTillBirthday” attribute.

---

<div class="post-metadata">

### Author: ![Mr.Red](https://community.silverbullet.md/user_avatar/community.silverbullet.md/mr.red/32/821_2.png) [@Mr.Red](https://community.silverbullet.md/u/Mr.Red)
#### Post date: [January 30, 2025, 2:01pm UTC](https://community.silverbullet.md/t/trouble-with-creating-a-variable-attribute-for-a-person-using-functions/1563/4 "2025-01-30T14:01:00Z")

</div>

> [@22rw](#):
>
> ```auto
> - where: 'tag = "person"'
> attributes:
> daysTillBirthday: 'daysTillBirthday(niceDate(birthday))'
> 
> ```

thanks, this worked like a charm.  
I was not aware I can declare attributes like this for Objects, only for pages.  
This is what i was looking for.

---

<div class="post-metadata">

### Author: ![22rw](https://community.silverbullet.md/user_avatar/community.silverbullet.md/22rw/32/659_2.png) [@22rw](https://community.silverbullet.md/u/22rw)
#### Post date: [January 30, 2025, 2:15pm UTC](https://community.silverbullet.md/t/trouble-with-creating-a-variable-attribute-for-a-person-using-functions/1563/5 "2025-01-30T14:15:41Z")

</div>

Glad I could help 😃
