# How to learn perspective the right way?

**URL:** <https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [September 22, 2022, 8:27am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362 "2022-09-22T08:27:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![hewking32](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@hewking32](https://forum.inductiveautomation.com/u/hewking32)\
**Post date:** [September 22, 2022, 8:27am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/1 "2022-09-22T08:27:06Z")

</div>

Hi  
I am learning perspective trying to be “project ready” (which might arrive soon).  
I covered perspective section of the inductive university and also elective study (Building in perspective which was excellent).  
Just wonder what would be the best idea to do next:  
1 I have demo VM which i might start analysing - is there any additional documentation related to the demo VM? or is the project self explanatory  
2 i consider reviewing all perspective library objects to have good gist what each of them does  
3 i find this forum very helpful so might start reading some posts about perspective  
4 any other projects apart from demo worth analysing or other ideas?

Regards

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [September 22, 2022, 8:32am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/2 "2022-09-22T08:32:51Z")

</div>

How’s your [python](https://www.w3schools.com/python/)?

---

<div class="post-metadata">

**Author:** ![hewking32](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@hewking32](https://forum.inductiveautomation.com/u/hewking32)\
**Post date:** [September 22, 2022, 8:39am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/3 "2022-09-22T08:39:30Z")

</div>

I would say medium level. Would it make sense to go through each object to have at least an idea what is available for future use?

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [September 22, 2022, 8:52am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/4 "2022-09-22T08:52:46Z")

</div>

Python and [CSS](https://www.w3schools.com/css/) will help you a lot in Perspective development.

Reading this forum is a big help too; there are a lot of great contributors who do amazing things with [Perspective](https://forum.inductiveautomation.com/search?expanded=true&q=tags%3Aperspective).

---

<div class="post-metadata">

**Author:** ![hewking32](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@hewking32](https://forum.inductiveautomation.com/u/hewking32)\
**Post date:** [September 22, 2022, 8:57am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/5 "2022-09-22T08:57:40Z")

</div>

thanks Justin for brilliant ideas. I definitely need to improve my knowledge of CSS because the screen have and work and look good.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [September 22, 2022, 9:06am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/6 "2022-09-22T09:06:08Z")

</div>

I have a personal sandbox project and create a view per component when I want to experiment. This allows me to mess around without affecting an active project and without clutter.

I find that monitoring this forum and trying to answer questions - even if I don’t post an answer - is very educational. Sometimes I post in the knowledge that someone else will subsequently post a better solution and that furthers my education.

You’ll find that many projects follow the Pareto rule. 20% of the work will take 80% of the time as you try to figure out how best to do some tasks. Use the forum!

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [September 22, 2022, 9:13am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/7 "2022-09-22T09:13:47Z")

</div>

I suggest familiarizing yourself with the different scopes as it’s not super intuitive when you first start scripting with ignition and might be a source of hair pulling and frustration 😛

You can also review the list of system functions, which are built-in ignition functions, so you’re familiar with what’s available:  
[https://docs.inductiveautomation.com/display/DOC81/System+Functions](https://docs.inductiveautomation.com/display/DOC81/System+Functions)

Then learn what expressions are, where, when and how to use them:  
[https://docs.inductiveautomation.com/display/DOC81/Expression+Language+and+Syntax](https://docs.inductiveautomation.com/display/DOC81/Expression+Language+and+Syntax)  
[https://docs.inductiveautomation.com/display/DOC81/Expression+Functions](https://docs.inductiveautomation.com/display/DOC81/Expression+Functions)

---

<div class="post-metadata">

**Author:** ![hewking32](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@hewking32](https://forum.inductiveautomation.com/u/hewking32)\
**Post date:** [September 22, 2022, 9:18am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/8 "2022-09-22T09:18:01Z")

</div>

Can you please share more details about sandbox environment and how this is set up as i have not used it yet. Is it similar to docker?

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [September 22, 2022, 9:23am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/9 "2022-09-22T09:23:52Z")

</div>

> [@hewking32](#):
>
> details about sandbox environment ...

No, just create a project called "Sandbox" (or "LearningProject" or whatever). You can then create views, write scripts, named queries, etc., to experiment and try stuff out. Then next time you need to experiment - with a table, for example - you open the project, go to the view with the table and begin your investigation.

---

<div class="post-metadata">

**Author:** ![hewking32](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@hewking32](https://forum.inductiveautomation.com/u/hewking32)\
**Post date:** [September 22, 2022, 9:34am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/10 "2022-09-22T09:34:45Z")

</div>

yep keeping things separate for experimenting is definitely a good idea as i did fall into the trap of forgetting to delete the rubbish 🙂

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [September 22, 2022, 9:58am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/11 "2022-09-22T09:58:04Z")

</div>

It’s how I let others know…

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/6/660e49bbdf28bc76d0c4cbe3e96deec23338923a.png)

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [September 22, 2022, 10:04am UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/12 "2022-09-22T10:04:56Z")

</div>

> [@Transistor](#):
>
> just create a project called “Sandbox” (or “LearningProject” or whatever)

Mine is called "scratchpad"

---

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [September 22, 2022, 1:08pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/13 "2022-09-22T13:08:51Z")

</div>

Project ready can mean a lot of things. If you are doing a project that requires responsive design you definitely want to get good with flex containers and breakpoint views.

When you’re first starting a project I recommend setting up styles and building a general screen layout because then you can just copy a screen to make a new screen and all of your screens are already referencing styles that you can later tweak to update the whole app.

I agree with the suggestion to make a sandbox project and learn about CSS and Python. It’s also a very good idea to learn your way around inkscape for making custom SVGs and save them as “optimized SVG” because it makes them a lot smaller. The Ignition developers are currently working on making embedded SVGs work a lot better and knowing how to do all of that really opens doors.

You can do a lot by adding custom properties onto controls and binding them to things that you want to use to trigger code. Basically, you bind the custom property to something that changes and put a script transform on that binding to run whatever code you want to run. Don’t use that with a now function to do time-based animations because you can do it a lot more efficiently with a css transform. That said, you can execute a good project without knowing how to do animations and all that. It’s just cooler if you can do all that also.

Learn about sending messages to pass information around your project.

Copy/paste things from Ignition into a text editor. This shows you the JSON structure of things and also gives you an understanding of things you can copy/paste.

---

<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:** [September 22, 2022, 2:22pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/14 "2022-09-22T14:22:26Z")

</div>

Get familiar with the developer tools in your chosen browser. Learning how to find the CSS style names that ignition is using in order to customize your look and feel is extremely important. Also, make sure you have multiple browsers to test in, sometimes what works in one doesn't work in another and the only way to know is to try.

Also, test in a real browser, some things just don't work the same when run from the designer. Using the designer is a good gut check but the best test is always the browser.

I would also recommend getting comfortable with JSON. Learning to recognize when a JSON string is valid or not comes in handy.

Also, here is a good post that I have bookmarked that really helped me when I was starting to pick up perspective.

> [@What's the guidlines for when to use a flex and when to use coordinate](https://forum.inductiveautomation.com/t/whats-the-guidlines-for-when-to-use-a-flex-and-when-to-use-coordinate/39879/4):
>
> The only time I find myself using a Coordinate container is when I need to layer components over one another (I have a Map component with a special UI overlay in a View), but even then I use the percent mode. I use a Breakpoint container if I know I want completely different components available between a mobile user or a desktop user. I use Column Containers If I want to use the EXACT same components between mobile and desktop but I want them in different spots. I use Flex containers for EVE…

---

<div class="post-metadata">

**Author:** ![nideyijuyidong](https://avatars.discourse-cdn.com/v4/letter/n/7cd45c/32.png) [@nideyijuyidong](https://forum.inductiveautomation.com/u/nideyijuyidong)\
**Post date:** [September 22, 2022, 2:42pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/15 "2022-09-22T14:42:34Z")

</div>

Sending messages is so useful, it amazed my fellow PLC engineers. 😄

---

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [September 22, 2022, 2:54pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/16 "2022-09-22T14:54:39Z")

</div>

Yes and another really cool thing you can do once you understand the JSON part (which you copy/paste into a text editor to see) is that you can put a script transform on a property that has sub properties and you can populate all of the sub properties in the script by returning JSON from your script transform.

That combined with an expression structure binding can turn into a function that gets called any time one of an number of parameters changes and dynamically builds a complex control layout. Play around with that. It’s amazing what you can do.

---

<div class="post-metadata">

**Author:** ![hewking32](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@hewking32](https://forum.inductiveautomation.com/u/hewking32)\
**Post date:** [September 22, 2022, 3:11pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/17 "2022-09-22T15:11:56Z")

</div>

Thanks for all replies so far. What about troubleshooting skills for perspective @lrose mentioned developer tools -definitely yes. What other tools/technique do you use for troubleshooting perspective ? I am already familiar with troubleshooting/tracing in vision  
regards

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 22, 2022, 3:14pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/18 "2022-09-22T15:14:39Z")

</div>

Here is also an old _essay_ I wrote about the topic lol. Still has some good gems in there.

> [@How do I master a Ignition Perspective?](https://forum.inductiveautomation.com/t/how-do-i-master-a-ignition-perspective/38189/2):
>
> I had to brute force my way through “mastering” perspective, and it still has many aspects that I am not sure I am handling perfectly correct. However here are a few tips I can provide for someone transitioning from Vision into Perspective for the first time. 1. The coordinate container is your enemy, and the flex container is your friend! Everyone ALWAYS seems to latch onto coordinate containers because they feel really familiar compared to vision, however the further you get into your journe…

The best part about the forums is there is a long history of questions like this that inevitably give people an opportunity to share their best practices with the community.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [September 22, 2022, 4:47pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/19 "2022-09-22T16:47:41Z")

</div>

The best way to troubleshoot anything in Perspective is to use logging. I recommend using a project script to do something like this:

```auto
# This is defined in a package named "Logger"
def log(name, msg)
    system.util.getLogger(name).info(str(msg)) # string casting for safety

```

Then you can easily call your logging anywhere in your Project (not tags, as they’re Gateway scoped) with this:

```auto
Logger.log("FocusAreaInUse", "What the next step is")

```

Including logging like this can easily help you determine what code is not being reached when troubleshooting logic.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 22, 2022, 5:16pm UTC](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362/20 "2022-09-22T17:16:19Z")

</div>

A comment on troubleshooting like this, it is super useful, however if you have a lot of different sessions you may want to see things in the specific sessions console or the designer.

I often use a wrapper class to add the capability to push logs into the web developer console, as well as the script console on top of this.

A link to the helper class I use is here: [https://github.com/design-group/gists/blob/master/GatewayLogger.py](https://github.com/design-group/gists/blob/master/GatewayLogger.py)

Using it is very similar to the above, and it uses the builtin `.info`, `.warn`, `.trace`, etc. functions to that its pretty seamless to switch to.

In the gateway logs you see regular messages, but if the correct logging level is enabled, you also see them in the perspective console or script console.

### Example script:

```python
logger = Logger.logger("FocusAreaInUse")
logger.trace("Step 1")
logger.info("Step 2")

```

### Example output (in all consoles):

```python
FocusAreaInUse.TRACE: Step 1
FocusAreaInUse.INFO: Step 2

```

[Next page](https://forum.inductiveautomation.com/t/how-to-learn-perspective-the-right-way/64362.md?page=2)
