/upstream/templates/lists/widget.tmpl
Type: /type/template
body: value: $def with (page, user_lists_only=False)

$if "lists" not in ctx.features:
    $return

$code:
    def get_seed_info():
        if page.key.startswith("/subjects/"):
            seed = page.key.split("/")[-1]
            if seed.split(":")[0] not in ["place", "person", "time"]:
                seed = "subject:" + seed
            seed = seed.replace(",", "_").replace("__", "_")
            seed_type = "subject"
            title = page.name
        else:
            seed = {"key": page.key}
            if page.key.startswith("/authors/"):
                seed_type = "author"
                title = page.get('name', 'name missing')
            elif page.key.startswith("/works"):
                seed_type = "work"
                title = page.get("title", "untitled")
            else:
                seed_type = "edition"
                title = page.get("title", "untitled")
        return seed, seed_type, title
    
    def get_list_data(list):
        d = storage({
            "name": list.name or "",
            "key": list.key,
            "active": list.has_seed(seed),
        })
        cover = list.get_cover() or list.get_default_cover()
        d['cover_url'] = cover and cover.url("S") or "/images/icons/avatar_book-sm.png"
        
        owner = list.get_owner()
        d['owner'] = storage(displayname=owner.displayname or "", key=owner.key)
        
        return d
    
    def get_user_lists():
        lists = ctx.user and ctx.user.get_lists(sort=False) or []
        return [get_list_data(list) for list in lists]
        
    def get_page_lists():
        user_key = ctx.user and ctx.user.key
        return [get_list_data(list) for list in page.get_lists(sort=False)]

    def get_user_list_index(list):
        for i, ulist in enumerate(user_lists):
            if ulist.key == list.key:
                return i        

$ seed, seed_type, title = get_seed_info()
$ user_lists = get_user_lists()
$if user_lists_only:
    $ page_lists = [list for list in user_lists if list.active]
$else:
    $ page_lists = get_page_lists()
$ user_key = ctx.user and ctx.user.key
$ page_url = page.url()

$var page_lists = page_lists

$jsdef show_list(list):
    $ remove = (list.owner.key == user_key)
    <li>
        <span class="image">
            <a href="$list.key"><img src="$list.cover_url" alt="Cover of: $list.name" title="Cover of: $list.name"/></a>
        </span>
        <span class="data">
            <span class="label">
                <a href="$list.key" title="See this list">$list.name</a>
                $if remove:
                    $ index = get_user_list_index(list)
                    <a href="$list.key" class="remove-from-list red smaller arial plain" id="list_$index" title="Remove from your list?">[X]</a>
            </span>
            $if remove:
                <span class="owner">from <a href="$list.owner.key">You</a></span>
            $else:
                <span class="owner">from <a href="$list.owner.key">$list.owner.displayname</a></span>
        </span>
    </li>

$jsdef render_widget_add(lists):
    <div class="dropit">
        <div class="icon list"></div> 
        <div class="dropper on">
            <a href="javascript:;" class="dropclick plain">
                <h3>Add to list</h3>
                <div class="arrow"></div>
            </a>
            <div class="dropdown">
                $for i, list in enumerate(lists):
                    $if not list.active:
                        <p class="list"><a href="$list.key" class="add-to-list" id="list_$i">$list.name</a></p> 
                <p class="create"><a href="javascript:;" id="create-new-list">Create a new list</a>
                    <a href="javascript:;" class="hidden listClick"></a>
                </p>
            </div> 
        </div> 
    </div>

$jsdef render_widget_display(lists, limit):
    $for i, list in enumerate(lists):
        $if i < limit:
            $:show_list(list)

$jsdef render_head():
    $if seed_type == "subject":
        <div class="head">
            <h3>Lists</h3>
            <div class="smallest lightgreen sansserif">watch for edits or export all records</div>
        </div>
    $else:
        <h4>
        $if len(page_lists) > 0:
            $ msg = ungettext("%s List", "%s Lists", len(page_lists))
            $sprintf(msg, len(page_lists))            
            $if len(page_lists) > 3:
                <span class="sansserif smaller"><a href="$page_url/lists">$_("See all")</a></span>
            $else:
                <span class="sansserif smaller"><a href="$page_url/lists">$_("Details")</a></span>
        $else:
            $_("Lists")
        </h4>

<div id="widget-head">
    $:render_head()
</div>

$if not ctx.user and not page_lists:
    <div class="sansserif small">You <em>could</em> add <strong>$title</strong> to a <a href="/lists" title="Learn more about lists">list</a> if you <a href="/account/login" title="Log in or sign up now">log in</a>.</div>
    
$if ctx.user:
    <div id="widget-add">
        $:render_widget_add(user_lists)
    </div>
    
<ul class="listLists">
    <div id="widget-lists">
        $:render_widget_display(page_lists, 3)
    </div>
</ul>
<div id="remove-dialog" class="hidden" title="Remove">Are you sure you want to remove <strong>$title</strong> for your list?</div>

$if ctx.user:
    <div class="hidden">
        <div class="floaterAdd" id="addList">
            <div class="floaterHead">
                <h2>Create a new list</h2>
                <a class="floaterShut" href="javascript:;" onclick="\$.fn.colorbox.close();"><span class="shift">$_("Close")</span></a>
            </div>
            <form method="post" action="" class="floatform" name="new-list" id="new-list">
            <div class="formElement">
                <div class="label">
                    <label for="list_label">Name:</label>
                </div>
                <div class="input">
                    <input type="text" name="list_label" id="list_label" class="text required" value=""/>
                </div>
            </div>
            <div class="formElement">
                <div class="label">
                    <label for="list_desc">Description:</label>
                </div>
                <div class="input">
                    <textarea name="list_desc" id="list_desc" rows="5" cols="30"></textarea>
                </div>
            </div>
            <div class="formElement">
                <div class="input">
                    <button type="submit" class="larger">Create new list</button>
                    &nbsp; &nbsp;
                    <a href="javascript:;" onclick="\$.fn.colorbox.close();" class="small plain red">Cancel</a>
                </div>
                <div class="label"></div>
            </div>
            </form>
        </div>
    </div>

    <script type="text/javascript">
    // Lists API

    Lists = {
        create: function(user, data, success) {
            this.ajax({
                url: user + "/lists.json",
                data: data,
                success: success
            });
        },
        add: function(list_key, seed, success) {
            this.ajax({
                url: list_key + "/seeds.json",
                data: {
                    'add': [seed]
                },
                success: success
            });
        },
        remove: function(list_key, seed, success) {
            this.ajax({
                url: list_key + "/seeds.json",
                data: {
                    'remove': [seed]
                },
                success: success
            });
        },
    
        ajax: function(d) {
            \$.ajax({
                type: "POST",
                url: d.url,
                contentType: "application/json",
                data: JSON.stringify(d.data),
                dataType: "json",
            
                beforeSend: function(xhr) {
                    xhr.setRequestHeader("Content-Type", "application/json");
                    xhr.setRequestHeader("Accept", "application/json");
                },
                success: d.success
            });
        }
    }

    </script>

    <script type="text/javascript">
    var seed = $:json_encode(seed);
    var seed_type = $:json_encode(seed_type);
    var title = $:json_encode(title);
    
    var user_lists = $:json_encode(user_lists);
    var page_lists = $:json_encode(page_lists);
    
    var user_key = $:json_encode(user_key);
    var page_url = $:json_encode(page_url);

    function reload_widget() {
        \$("#widget-head").html(render_head());
        \$("#widget-add").html(render_widget_add(user_lists));
        \$("#widget-lists").html(render_widget_display(page_lists, 3));
        setup_events();

        // We've added new .dropclick element. Need to setup listeners again.
        \$('.dropclick').click(function(){
            \$(this).next('.dropdown').slideToggle();
            \$(this).parent().find('.arrow').toggleClass("up");
        });
        
        // Trigger an event to allow adding listeners
        \$(window).trigger("ol.lists");
    }
    
    function get_user_list_index(list) {
        for (var i=0; i< user_lists.length; i++) {
            if (list.key == user_lists[i].key) {
                return i;
            }
        }
    }

    function get_list(id) {
        // strip "list_" from id.
        id = id.substr(5);
        return user_lists[parseInt(id)];
    }
    
    function add_page_list(list) {
        page_lists.splice(0, 0, list);
    }
    
    function remove_page_list(list) {
        for (var i=0; i<page_lists.length; i++) {
            var pagelist = page_lists[i];
            if (page_lists[i].key == list.key) {
                page_lists.splice(i, 1);
                break;
            }
        }
    }
    
    function setup_submit_event() {
        // This form in creted only at the begining. 
        // Unlike other elements, event for this form should be setup only once.
        \$("#new-list").ol_validate({
            submitHandler: function(form) {
                var data = {
                    name: \$("#list_label").val(),
                    description: \$("#list_desc").val(),
                    seeds: [seed]
                };

                Lists.create("$ctx.user.key", data, function(d) {
                    \$.fn.colorbox.close();
                    var list = {
                      key: d.key,
                      name: data.name,
                      active: true,
                      owner: {key: user_key},
                      cover_url: "/images/icons/avatar_book-sm.png",

                      edition_count: 1,
                      description: websafe(data.description)
                    };
                    user_lists[user_lists.length] = list;
                    add_page_list(list);

                    reload_widget();
                });
                return false;
            }
        });
    }
            
    function setup_events() {
        \$(".listClick").colorbox({inline: true, opacity: "0.5", href: "#addList"});
    
        \$("#create-new-list").click(function() {
           close_popup();
           \$(".listClick").click(); 
        });

        \$("a.add-to-list").click(function(event) {
            event.preventDefault();
            close_popup();
        
            var id = \$(this).attr("id");
            var list = get_list(id);
        
            Lists.add(list.key, seed, function() {
                list.active = true;
                add_page_list(list);
                reload_widget();
            });
            return false;
        });
    
        \$("a.remove-from-list").click(function(event) {
            event.preventDefault();
            var id = \$(this).attr("id");
            
            \$("#remove-dialog")
                .data("list-id", id)
                .dialog("open");
            return false;
        });
    }

    function close_popup() {
        \$(this).next('.dropdown').slideToggle();
        \$(this).parent().find('.arrow').toggleClass("down");
    } 
    
    function setup_dialog() {
        \$("#remove-dialog").ol_confirm_dialog(function() {
            var id = \$(this).data("list-id");
            var list = get_list(id);
            var _this = this;

            Lists.remove(list.key, seed, function() {
                list.active = false;
                remove_page_list(list);
                reload_widget();
                \$(_this).dialog("close");
            });
        });

    }

    \$().ready(function(){
        setup_submit_event();
        setup_events();
        setup_dialog();

        var mylist = \$('.dropdown');
        var listitems = mylist.children('p.list').get();
        var listcreate = \$('.dropdown p.create');
        var a = a;
        var b = b;
        listitems.sort(function(a, b) {
           var compA = \$(a).text().toUpperCase();
           var compB = \$(b).text().toUpperCase();
           return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
        })
        \$.each(listitems, function(idx, itm) { mylist.append(itm); });
        \$('.dropdown').append(listcreate);
    });

    </script>
plugin: openlibrary
title: Lists widget for edition, work, author, subject
m: edit