# Use CSS Variable instead of Python Script

**URL:** <https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [August 7, 2023, 1:45am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501 "2023-08-07T01:45:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [August 7, 2023, 1:45am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/1 "2023-08-07T01:45:05Z")

</div>

I want to bind a parameter from the return of a python script.  
But my script does not get evaluated, as you can see, I put "1" on expression and use a script transform - I used to do this but just found that this is bad strategy.

How can I get the script evaluated, when each parameters used on the script changes.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/f/efbce8c378e7888df85510f07d9c395b9ecb2087.png)

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 7, 2023, 2:55am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/2 "2023-08-07T02:55:25Z")

</div>

Transforms are only evaluated if their parent is re-evaluated. A static expression value like 1 is only evaluated once at first load. You need to use an expression structure binding and bind to all of your props you want to monitor for this to evaluate when these props change

~~I think~~ You can also include all your props in a group (object/array) and just monitor the group prop itself

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [August 7, 2023, 3:34am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/3 "2023-08-07T03:34:59Z")

</div>

That is what I observed.  
Thanks.  
Time to practice expression structure.  
I watched it a few times but didn't learn it.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 7, 2023, 6:13pm UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/4 "2023-08-07T18:13:38Z")

</div>

Split this topic on August 7, 2023, 6:13pm UTC

15 posts were split to a new topic: [Expression structure binding woes](https://forum.inductiveautomation.com/t/expression-structure-binding-woes/77533)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 7, 2023, 11:24am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/10 "2023-08-07T11:24:48Z")

</div>

You could use `asList()` in an expression binding to produce a composite of several "monitored" tags/properties to pass to your transform as `value`. Something like this:

```auto
asList({path.to.prop1}, {path.to.prop2}, {path/to/tag1}, {path/to/tag2})

```

if you do this, I recommend exploding back to local variables in the first line of the script transform:

```auto
def transform(self, value, quality, timestamp):
	prop1, prop2, tag1, tag2 = value
	.... the rest of the transform ....

```

This approach can also be used with expression transforms to ensure source values or sub-expressions are evaluated only once before inclusion in a larger expression.

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [August 7, 2023, 11:26pm UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/11 "2023-08-07T23:26:08Z")

</div>

Hi,

I am playing with expression structure now..  
On expression Editor. I added tags. But how do you make the tags dynamic such as below:  
I want to make the motor index number to be dynamic:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/3/838b1adda1aad0e116c838a5c1b3f55e953cd900.png)  
Is that even possible?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 7, 2023, 11:42pm UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/12 "2023-08-07T23:42:47Z")

</div>

That would be an **indirect tag binding**.

Putting curly braces into a string doesn't create a binding. Click on the chain link icon in the left gutter next to the property to open the binding editor.

{ And consider going through Inductive University, so you get all of these basics at a steady pace. }

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [August 8, 2023, 12:08am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/13 "2023-08-08T00:08:11Z")

</div>

I see. but there is no indirect binding in this option only expression binding..  
I made a work around by doing this on a custom parameter, where I can use Indirect Binding.

---

<div class="post-metadata">

**Author:** ![GregCavazos](https://avatars.discourse-cdn.com/v4/letter/g/ee7513/32.png) [@GregCavazos](https://forum.inductiveautomation.com/u/GregCavazos)\
**Post date:** [August 8, 2023, 12:55am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/14 "2023-08-08T00:55:14Z")

</div>

> [@pturmel](#):
>
> You could use `asList()` in an expression binding to produce a composite of several "monitored" tags/properties to pass to your transform as `value`.

Most likely I am looking at the wrong spot, but I cannot find `asList()` in the funtions on the Edit Binding popup.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 8, 2023, 1:47am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/15 "2023-08-08T01:47:00Z")

</div>

That’s because the `asList()` expression function is part of @pturmel‘a free SimulationAids Module.

> [@Automation Professionals' Integration Toolkit Module](https://forum.inductiveautomation.com/t/automation-professionals-simulation-aids-v2/74934):
>
> Automation Professionals is pleased to announce the immediately availability of a major upgrade to its free Simulation Aids Integration Toolkit module. The new feature justifying the "major upgrade" language is the implementation of eleven thirty-one new expression functions which use iteration to accomplish complex transforms of datasets and lists, to or from other datasets and lists, applying filtering, ordering, and computed new columns along the way. While there are certain operations that…

---

<div class="post-metadata">

**Author:** ![GregCavazos](https://avatars.discourse-cdn.com/v4/letter/g/ee7513/32.png) [@GregCavazos](https://forum.inductiveautomation.com/u/GregCavazos)\
**Post date:** [August 8, 2023, 1:49am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/16 "2023-08-08T01:49:47Z")

</div>

> [@lrose](#):
>
> That’s because the `asList()` expression function is part of @pturmel‘a free SimulationAids Module.

I see, is there any native way to accomplish similar thing? I dont opose to use the SimulationAids module, but would need to consult with customers if they apporve.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 8, 2023, 4:20am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/17 "2023-08-08T04:20:48Z")

</div>

No there isn’t a native way to do that in the expression language.

I suppose that you could use runScript to accomplish something similar, but that isn’t really a pure expression.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 8, 2023, 12:32pm UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/18 "2023-08-08T12:32:08Z")

</div>

> [@GregCavazos](#):
>
> but would need to consult with customers if they apporve.

Of course, and you should. It is too useful to not deploy **everywhere**. IMNSHO.

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [August 11, 2023, 4:24am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/19 "2023-08-11T04:24:09Z")

</div>

Back to the original post.

I want to bind a python script. such as below.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/0/00ab06d87edac4073c192990dde08f5ba0c1c116.png)

This I only set once and not tend to change. Thus this does not need to be triggered in runtime.  
I set 1 in the expression.  
But I ran into issues where the parameter will be set to null.

Is there a property I can monitor that change during startup, to use it to trigger this script?

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 11, 2023, 4:32am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/20 "2023-08-11T04:32:52Z")

</div>

If it doesn’t need to be triggered at runtime then why have a binding at all?? That just doesn’t even make since.

Also, for what you have shown here, there is no need for a script transform, just use an expression.

Why do you need a custom script in this way? This isn’t really what bindings are intended for.

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [August 11, 2023, 4:34am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/21 "2023-08-11T04:34:42Z")

</div>

> [@lrose](#):
>
> If it doesn’t need to be triggered at runtime then why have a binding at all?? That just doesn’t even make since.
> 
> Also, for what you have shown here, there is no need for a script transform, just use an expression.

Because, the data source I am binding to the parameter comes from python variable. That is shared through out the project.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 11, 2023, 5:04am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/22 "2023-08-11T05:04:29Z")

</div>

> [@Eugene49](#):
>
> the data source I am binding to the parameter comes from python variable.

What data source?

Even in the new image that you provided after the edit, the script can easily be duplicated in a pure expression.

```auto
if(toInt({parameter}) % 2,{view.custom.theme.tableOdd},{view.custom.theme.tableEven})

```

If what you’re attempting to do is apply a theme style, I feel like you’re making it much more difficult than it needs to be.

You should be creating a theme file, style classes, or custom classes in a stylesheet, and then applying those to your components.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 11, 2023, 5:22am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/23 "2023-08-11T05:22:09Z")

</div>

> [@lrose](#):
>
> You should be creating a theme file, style classes, or custom classes in a stylesheet, and then applying those to your components.

@Eugene49 Just to be clear, you generally _should not_ be assigning "[magic](https://en.wikipedia.org/wiki/Magic_number_(programming))" values like colour hex's directly to style properties like `backgroundColo(u)r` if you want to have any hope of maintaining a theme throughout your project. Ditch these in favour of Perspective Styles, as @lrose suggested

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [August 11, 2023, 6:06am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/24 "2023-08-11T06:06:35Z")

</div>

do you guys mean. If you want to set label's font color to green. you would rather create a style, set font color to green and apply the style?

Hypothetically, Say I have 4 layers of nested flex container.  
Each layer uses different background color.  
You would rather create 4 styles. Layer1 .. Layer4 styles. Apply these style to each flex container respectively.

What I did, I created 4 global variables in python, and pass those variables to background of each flex? To remain consistent project wide.  
What is wrong with this?

Also, if I decided to create a css theme file.  
Would I able to distinguishly identify the 4 flex container above and set different color to them?  
Or theme can only be applied as per component type.

Anyway, my problem is not about the strategy above nor the choice to use expression vs python script.  
Python is more readable for me. Is there an advantage favoring the use of expression?

My problem is, for some reason, the parameter forgets the value that was set to it, during saving/closing/reopening of view.. and since the binding does not get triggered, it returns an error.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 11, 2023, 6:16am UTC](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501/25 "2023-08-11T06:16:21Z")

</div>

> [@Eugene49](#):
>
> Is there an advantage favoring the use of expression?

Expressions are more performant than script transforms and will reduce the load on your gateway. This is especially important for larger systems

> [@Eugene49](#):
>
> e parameter forgets the value that was set to it, during saving/closing/reopening of view

The whole scripting engine restarts every time you save the project.

> [@Eugene49](#):
>
> do you guys mean. If you want to set label's font color to green. you would rather create a style, set font color to green and apply the style?
> 
> Hypothetically, Say I have 4 layers of nested flex container.  
> Each layer uses different background color.  
> You would rather create 4 styles. Layer1 .. Layer4 styles. Apply these style to each flex container respectively.
> 
> What I did, I created 4 global variables in python, and pass those variables to background of each flex? To remain consistent project wide.  
> What is wrong with this?

Using Perspective Styles are far more performant than reading variables from script libraries within a script transform, they're also far more obvious and user friendly for other engineers when maintaining or extending a project. Design for performance and user experience first; script transforms should only ever be the last option if you can't achieve the same thing via other methods (e.g. tag / expression bindings)

Yes, I would create 4 styles in that case, assuming they're used in more than one place.

[Next page](https://forum.inductiveautomation.com/t/use-css-variable-instead-of-python-script/77501.md?page=2)
