Using Arguments and Adding Menu to Kodi Add-ons

Following our first tutorial explaining how to create your first Kodi add-on, the next steps will be to use the arguments the Kodi passes to the add-on and add a menu for this add-on. This tutorial is based on the Python code created in the previous tutorial.

Python

The source code for this tutorial is found in GitHub here.

Let’s start explaining this source code in detail.

How to use arguments with the add-on

Kodi passes three arguments to every add-on. Those arguments are kept in a list called sys.argv

IDDescription
0The base URL of the add-on, for example: plugin://script.hello.world/
1The handle of the add-on, which is an integer number
2The query string passed to the add-on, for example:
?param1=AAA&param2=BBB
base_url = sys.argv[0]

This is how we get the first argument, which is the base URL.

addon_handle = int(sys.argv[1])

We also get the second argument, which is the add-on handle, and convert it from string to integer.

args = urlparse.parse_qs(sys.argv[2][1:])

Here we get the third argument, which is the query string, but we need to do some manipulation on it. [1:] means omitting the first character in the query string, which is ?. The function parse_qs converts the query string to list of parameters, so we can get the value of each parameter.

def build_url(query):
return base_url + '?' + urllib.urlencode(query)

Here we define a function that build a URL based on the base URL and the query string.

xbmcplugin.setContent(addon_handle, 'movies')

Here we set the content type of the add-on to movies. Other possible values can be: tvshows, episodes, songs, artists, albums, musicvideos, files.

mode = args.get('mode', None)

The menu in our case has two levels and each level has different items. The mode variable is used to check the level, so the right menu items are displayed. We check the value of the mode parameter and assign its value to the mode variable. If the mode parameter doesn’t exist, we assign None.

if mode is None:

If mode is None, it means that we are in the first level of the menu. In this case two folders are displayed (folder A and folder B) as the items of the menu.

elif mode[0] == 'folder':

If mode is a folder, it means that we are in the second level of the menu. In this case a file is displayed as the item of the menu. Clicking on it will open a video.

url = build_url({'mode': 'folder', 'foldername': 'Folder A'})

Here is how we invoke the build_url function and create the query string according to the parameters inside the curly brackets. In this case the query string is the following: mode=folder&foldername=Folder+A

foldername = args['foldername'][0]

Here is how we get the foldername parameter for the query string, which was already converted to list.

How to add a menu to the add-on

Menus help us navigate throughout the add-on. If the content has some hierarchy, menus can reflect this.

li = xbmcgui.ListItem('Folder A', iconImage='DefaultFolder.png')

In order to create a menu, we first need to create ListItem, which is one item in the menu. In this case the item is folder A and it has a default folder image.

xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li, isFolder=True)

Here is how we add the item to the directory, which is our menu. We indicate  if the item is a folder or a file using the isFolder attribute.

xbmcplugin.endOfDirectory(addon_handle)

This function ends the directory, which means closing the menu definition.

How to test the new add-on

First lets change the add-on so it can accept arguments and also change its type to video add-on. In the file addon.xml change the following XML code from:

<extension point="xbmc.python.script" library="addon.py">
<provides>executable</provides>
</extension>

To this code:

<extension point="xbmc.python.pluginsource" library="addon.py">
<provides>video</provides>
</extension>

Now you can copy the source code, paste it to the file addon.py (replace the entire content of this file) and test the new add-on.

Leave a Reply

Your email address will not be published. Required fields are marked *