Skip to content

Skin Variable Builder

jurialmunkey edited this page May 15, 2023 · 8 revisions

Variable Builder

SkinVariables provides a tool for skinners to create a variable template which generates variables for multiple containers and/or list items.

To use this feature, create an xml file in the skin's shortcuts directory

kodi/addons/SKINNAME/shortcuts/skinvariables.xml

The Template

In the skinvariables.xml you create a template like so

<?xml version="1.0" encoding="UTF-8"?>
<includes>
    <variable name="Image_Poster" containers="51,52" start="1" end="2" parent="Control.HasFocus({id})" null_id="True">
        <value condition="!String.IsEmpty({listitem}.Art(tvshow.poster))">$INFO[{listitem}.Art(tvshow.poster)]</value>
        <value condition="!String.IsEmpty({listitem}.Art(poster))">$INFO[{listitem}.Art(poster)]</value>
    <variable>
    <expression name="Exp_Poster" containers="51,52" start="1" end="2" null_id="True">[!String.IsEmpty({listitem}.Art(poster)) | !String.IsEmpty({listitem}.Art(tvshow.poster))]</expression>
</includes>
Tag Purpose
"name" [required] The name of the variable or expression to build. One variable/expression will be built for each container specified in the container tag and for each listitem in the range from start tag to end tag. The naming pattern of each variable created is {name}_C{id}_{pos}
"containers" [optional] A comma separated list of the containers to build variables for. Variables are also built without a container. AS of v1.1.0+ optionally can use an ellipsis ... to specify a range - e.g. containers="1...10,20" will build all container IDs from 1 to 10, as well as container ID 20
"start" / "end" [optional] The start and end listitem position range to build variables for. A separate variable is built for every listitem position in the range for every specified container. Variables are also built for no listitem position.
"parent" [optional] Builds a parent variable {name}_Parent that selects the container variable based on the rule.
"null_id" [optional] Builds an additional container variable {name}_Container using Container.ListItem without a container ID. v1.1.1+
Key Purpose
{listitem} Replaced by the specific container and listitem - e.g. in Image_Landscape_C51_5 it will be Container(51).ListItem(5).
{listitemabsolute} Like {listitem} but the absolute position - e.g. Container(51).ListItemAbsolute(5).
{listitemnowrap} Like {listitem} but the nowrap position - e.g. Container(51).ListItemNoWrap(5).
{listitemposition} Like {listitem} but the onscreen position - e.g. Container(51).ListItemPosition(5).
{id} The container ID - e.g. Container({id}).
{pos} The listitem position - e.g. ListItem({pos})
{cid} The container ID name for referencing variables e.g. $VAR[OtherVariable{cid}] is $VAR[OtherVariable_C50] if id=50; {cid} will be empty if container ID is None
{lid} The listitem position ID name for referencing variables e.g. $VAR[OtherVariable{lid}] is $VAR[OtherVariable_3] if pos=3; {lid} will be empty if listitem position ID is None

NOTE: As of 1.0.2 you can combine the {cid} and {lid} to reference other variables constructed by skinvariables. e.g. $VAR[OtherVariable{cid}{lid}] is $VAR[OtherVariable_C50_3] if {id}=50 and {pos}=3 $VAR[OtherVariable_C50] if {id}=50 and {pos}=None $VAR[OtherVariable_3] if {id}=None and {pos}=3 $VAR[OtherVariable] if {id}=None and {pos}=None

Building the Variables

To build the variables from the template

runscript(script.skinvariables,action=buildvariables)

The script will only build the variables if the template has changed.
You can force a rebuild by adding the force argument runscript(script.skinvariables,action=buildvariables,force)

This command will generate a file in the skin's xml folder called script-skinvariables-includes.xml
You can optionally specify the folder with the folder argument runscript(script.skinvariables,action=buildvariables,folder=1080i)

Include this file in your Includes.xml

<include file="script-skinvariables-includes.xml" />

A variable for each position in the listitem range and for each container specified will be outputted to that includes file. Additionally, a base variable without any container or position will be built.

For instance, the above example will build:

<variable name="Image_Poster_Parent">
    <value condition="Control.HasFocus(51)">$VAR[Image_Poster_C51]</value>
    <value condition="Control.HasFocus(52)">$VAR[Image_Poster_C52]</value>
    <value condition="True">$VAR[Image_Poster]</value>
</variable>
<variable name="Image_Poster_Container">
    <value condition="!String.IsEmpty(Container.ListItem.Art(tvshow.poster))">$INFO[Container.ListItem.Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(Container.ListItem.Art(poster))">$INFO[Container.ListItem.Art(poster)]</value>
</variable>
<variable name="Image_Poster">
    <value condition="!String.IsEmpty(ListItem.Art(tvshow.poster))">$INFO[ListItem.Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(ListItem.Art(poster))">$INFO[ListItem.Art(poster)]</value>
</variable>
<variable name="Image_Poster_C51">
    <value condition="!String.IsEmpty(Container(51).ListItem.Art(tvshow.poster))">$INFO[Container(51).ListItem.Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(Container(51).ListItem.Art(poster))">$INFO[Container(51).ListItem.Art(poster)]</value>
</variable>
<variable name="Image_Poster_C51_1">
    <value condition="!String.IsEmpty(Container(51).ListItem(1).Art(tvshow.poster))">$INFO[Container(51).ListItem(1).Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(Container(51).ListItem(1).Art(poster))">$INFO[Container(51).ListItem(1).Art(poster)]</value>
</variable>
<variable name="Image_Poster_C51_2">
    <value condition="!String.IsEmpty(Container(51).ListItem(2).Art(tvshow.poster))">$INFO[Container(51).ListItem(2).Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(Container(51).ListItem(2).Art(poster))">$INFO[Container(51).ListItem(2).Art(poster)]</value>
</variable>
<variable name="Image_Poster_C52">
    <value condition="!String.IsEmpty(Container(52).ListItem.Art(tvshow.poster))">$INFO[Container(52).ListItem.Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(Container(52).ListItem.Art(poster))">$INFO[Container(52).ListItem.Art(poster)]</value>
</variable>
<variable name="Image_Poster_C52_1">
    <value condition="!String.IsEmpty(Container(52).ListItem(1).Art(tvshow.poster))">$INFO[Container(52).ListItem(1).Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(Container(52).ListItem(1).Art(poster))">$INFO[Container(52).ListItem(1).Art(poster)]</value>
</variable>
<variable name="Image_Poster_C52_2">
    <value condition="!String.IsEmpty(Container(52).ListItem(2).Art(tvshow.poster))">$INFO[Container(52).ListItem(2).Art(tvshow.poster)]</value>
    <value condition="!String.IsEmpty(Container(52).ListItem(2).Art(poster))">$INFO[Container(52).ListItem(2).Art(poster)]</value>
</variable>

<expression name="Exp_Poster">[String.IsEmpty(ListItem.Art(poster)) + String.IsEmpty(ListItem.Art(tvshow.poster))]</expression>
<expression name="Exp_Poster_Container">[String.IsEmpty(Container.ListItem.Art(poster)) + String.IsEmpty(Container.ListItem.Art(tvshow.poster))]</expression>
<expression name="Exp_Poster_C51">[String.IsEmpty(Container(51).ListItem.Art(poster)) + String.IsEmpty(Container(51).ListItem.Art(tvshow.poster))]</expression>
<expression name="Exp_Poster_C51_1">[String.IsEmpty(Container(51).ListItem(1).Art(poster)) + String.IsEmpty(Container(51).ListItem(1).Art(tvshow.poster))]</expression>
<expression name="Exp_Poster_C51_2">[String.IsEmpty(Container(51).ListItem(2).Art(poster)) + String.IsEmpty(Container(51).ListItem(2).Art(tvshow.poster))]</expression>
<expression name="Exp_Poster_C52">[String.IsEmpty(Container(52).ListItem.Art(poster)) + String.IsEmpty(Container(52).ListItem.Art(tvshow.poster))]</expression>
<expression name="Exp_Poster_C52_1">[String.IsEmpty(Container(52).ListItem(1).Art(poster)) + String.IsEmpty(Container(52).ListItem(1).Art(tvshow.poster))]</expression>
<expression name="Exp_Poster_C52_2">[String.IsEmpty(Container(52).ListItem(2).Art(poster)) + String.IsEmpty(Container(52).ListItem(2).Art(tvshow.poster))]</expression>