Object type and settings to use for toggling options?



I am generating a list of TVShowObjects to display. At the very top of the list, I want to add a "Sort Toggle" item that, when selecting, will cycle through various options for sorting the list of shows. It seemed like a DirectoryObject was the closest thing to what I needed. However, when I select the directory object, the client treats this like a stack where the previous sort label is the title, and where hitting "back" takes you back to the previous sort. (Which I guess makes sense if you treat this like a file directory.) A visible effect of this is that the title of the object is then displayed as the heading of the new page, which means it shows the old sort method...

It seems to me however that either the "no_history" or "replace_parent" flag in the ObjectContainer should override this behavior, but I am noticing no difference when I set either of those (or both of them) to True. I've also tried "mixed_parents", also to no effect...

Is there any Object I can use that will keep my navigation on the "same level" of the stack?

Here is my code:
def DisplayEpisodesData(episode_list):
oc = ObjectContainer(
no_history=True, # I've tried all 3 of these by themselves and in combination, no noticable difference...
key = Callback(ChangeSort),
title = "Sorted %s (Change)" % (cur_sort)))

all my shows are added down here...

return oc

@route(PREFIX + '/changesort')
def ChangeSort():
global cur_sort
cur_sort = SortOrder.next()

Log("Changed to "+cur_sort)
return MainMenu()

Any suggestions?


There is a PrefsObject that will open channel preferences and it should not mess up browsing history.


PrefsObject works great in the clients that have it, unfortunately Roku doesn't... So I'm trying to use the DumbPrefs class that coryo123 make for that specific reason, but unfortunately running into one more issue then... I created a new thread for that.


I see. Unfortunately I don't have any experience with DumbPrefs, but I can think of a couple of workarounds that might partially work:

  1. After changing sort order, redirect back to main menu rather than call its function directly. I think it would still add to a history, but it will be another main menu copy rather than returning to the previous sort order, which might be acceptable.
  2. Alternatively, you could try to return an empty ObjectContainer with a message. I don't know about Roku, but Plex Home Theater displays the message and then throws the user out to the channel list. Could be acceptable too because the user would then start a new browsing history and it's not a long way from the main menu. Of course, Roku may handle messages like that differently, if you're lucky, it could even let you stay at the same screen :)


return ObjectContainer(message='The sort order has changed to %s' % cur_sort)


Looking at the library, it already tried your #2 solution. Unfortunately, returning an empty ObjectContainer() on the Roku just displays the error "No items to display: This listing appears to be empty" and doesn't take you back out...

If I try a redirect(), where and how do you think would be appropriate? The "ValidatePrefs()" callback is getting called, so I think that is a sensible place to put the redirect, but trying "Redirect('/video/tvmonitor')" (or even "return Redirect('/video/tvmonitor')" ) doesn't redirect.


I would expect Redirect to work when used instead of return MainMenu(), based on the code you've posted above... Try return Redirect(PREFIX) to exclude a possibility of a typo in the URL path (assuming you use @handler(PREFIX, ...) decorator with the MainMenu function). Or check the function using a plain browser request for the channel XML, for me it turned out that, together with channel log files, these two are the first to-go places when anything doesn't work as expected. The redirect itself must work on Roku, you've already confirmed that.


And just to make sure, have you tried a "really" empty ObjectContainer() or one with a message ObjectContainer(message=...)? These could be treated differently by the clients. Plex Home Theater prints "No items to display" error for the first one too, but displays a pop-up message box for the second.


@czukowski said:
And just to make sure, have you tried a “really” empty ObjectContainer() or one with a message ObjectContainer(message=...)? These could be treated differently by the clients. Plex Home Theater prints “No items to display” error for the first one too, but displays a pop-up message box for the second.

Yep, returning a truly empty ObjectContainer(). The code in DumbTools for setting the value is:

    def Set(self, key, value):
        HTTP.Request("%s/:/plugins/%s/prefs/set?%s=%s" % (self.host,
                                                          key, value),
        return ObjectContainer()

I’m trying going back to my earlier hacky way of making a DirectoryObject, because that seems closer to working. Returning “Redirect(PREFIX)” does take me to the right place, and seems more legitimate than when I was doing “return MainMenu()”… (Functionally, it seems identical.)

But that leaves me with the visual artifact that I can’t figure out how to get rid of:

I’m displaying the current “sort order” is the DirectoryObject, and that shows up correctly. But once you’ve selected it and it changes, Plex says you’ve moved down in the directory, and “helpfully” displays the directory as the new title1 on the resorted page. I had hoped that either “no_history” or “replace_parent” on the ObjectContainer would possibly remove that, but frankly both those options seem to do nothing at all.

I see two approaches to a solution, but not sure which would be workable.

  1. Change the DirectoryObject’s title to just be “Change Sort”, and find some other way to display the current sort method. I’m not sure what other way there is… Maybe another DirectoryObject with an empty callback? Wastes screen real estate, but at least isn’t confusing… But would still leave “change sort” as the title of the page once changed.
  2. Figure out how to override the Title1 of the child ObjectContainer, so it doesn’t display it. This would be more ideal, but possibly undoable…


So if I understand it correctly, it seems that Roku actually registers the action that has produced a redirect into the browsing history, same as if you do return MainMenu() and you're back at the original issue. I'm not aware of any standard that governs browsing history and redirects, so I guess we can't tell whether it's a client bug or not. But it means that redirect will not solve the issue.

You may (and should :)) certainly try these two approaches, but I think changing the title won't take away the issue with the back button as it would still take you back to another sorting order change. Why don't you try to return ObjectContainer(message='Boom!'), ie with a message and not truly empty, instead of return Redirect(PREFIX) or return MainMenu() and see what happens?


I tried "return ObjectContainer(message='Boom!')" and it is different behavior, but not in a good way... Still says no items, then the message, and then nothing visually changes (despite my log files showing that the sort value was changed).

I ended up going with my #1 way: Add two items, "Change Sort" and "Sorted by %s"%cur_sort. "Change Sort" has a callback that increments the sort value and then returns Redirect(PREFIX), and "Sorted by" has a callback then just returns Redirect(PREFIX) and does nothing else...

Still leaves the screen with the directory nav structure, but at least the user never sees two different "Sorted By"s on the same screen.

Thanks for all of your help!