diff --git a/docs/docs/configuration/client.rst b/docs/docs/configuration/client.rst index 4db5151..db7b3cd 100644 --- a/docs/docs/configuration/client.rst +++ b/docs/docs/configuration/client.rst @@ -50,3 +50,13 @@ data-isso-reply-to-self ----------------------- Set to `true` when spam guard is configured with `reply-to-self = true`. + +data-isso-id +------------ + +Set a custom thread id, defaults to current URI. If you a comment counter, add +this attribute to the link tag, too. + +.. code-block:: html + +
diff --git a/isso/js/app/api.js b/isso/js/app/api.js index ece73b5..d13cbca 100644 --- a/isso/js/app/api.js +++ b/isso/js/app/api.js @@ -111,8 +111,8 @@ define(["q"], function(Q) { return rv.substring(0, rv.length - 1); // chop off trailing "&" }; - var create = function(data) { - return curl("POST", endpoint + "/new?" + qs({uri: location}), JSON.stringify(data)).then( + var create = function(tid, data) { + return curl("POST", endpoint + "/new?" + qs({uri: tid || location}), JSON.stringify(data)).then( function (rv) { return JSON.parse(rv.body); }); }; @@ -137,9 +137,9 @@ define(["q"], function(Q) { }); }; - var fetch = function(plain) { + var fetch = function(tid) { - return curl("GET", endpoint + "/?" + qs({uri: location, plain: plain}), null).then(function (rv) { + return curl("GET", endpoint + "/?" + qs({uri: tid || location}), null).then(function (rv) { if (rv.status === 200) { return JSON.parse(rv.body); } else { @@ -148,8 +148,8 @@ define(["q"], function(Q) { }); }; - var count = function(uri) { - return curl("GET", endpoint + "/count?" + qs({uri: uri}), null).then(function(rv) { + var count = function(tid) { + return curl("GET", endpoint + "/count?" + qs({uri: tid || location}), null).then(function(rv) { return JSON.parse(rv.body); }); }; diff --git a/isso/js/app/count.js b/isso/js/app/count.js index 173dab5..077b7f5 100644 --- a/isso/js/app/count.js +++ b/isso/js/app/count.js @@ -5,11 +5,13 @@ define(["app/api", "app/dom", "app/markup"], function(api, $, Mark) { return; } - var uri = el.href.match("^(.+)#isso-thread$")[1] + var tid = el.getAttribute("data-isso-id") || + el.href.match("^(.+)#isso-thread$")[1] .replace(/^.*\/\/[^\/]+/, ''); - api.count(uri).then(function(rv) { + + api.count(tid).then(function(rv) { el.textContent = Mark.up("{{ i18n-num-comments | pluralize : `n` }}", {n: rv}); }); }); }; -}); \ No newline at end of file +}); diff --git a/isso/js/app/isso.js b/isso/js/app/isso.js index db06d40..b374614 100644 --- a/isso/js/app/isso.js +++ b/isso/js/app/isso.js @@ -59,7 +59,7 @@ define(["app/text/html", "app/dom", "app/utils", "app/config", "app/api", "app/m return; } - api.create({ + api.create($("#isso-thread").getAttribute("data-isso-id"), { author: $("[name=author]", el).value || null, email: $("[name=email]", el).value || null, text: $("textarea", el).value, diff --git a/isso/js/embed.js b/isso/js/embed.js index 20532f2..0ad860d 100644 --- a/isso/js/embed.js +++ b/isso/js/embed.js @@ -26,7 +26,7 @@ require(["ready", "app/config", "app/api", "app/isso", "app/count", "app/dom", " $("#isso-thread").append(new isso.Postbox(null)); $("#isso-thread").append('
'); - api.fetch().then(function(rv) { + api.fetch($("#isso-thread").getAttribute("data-isso-id")).then(function(rv) { if (! rv.length) { $("#isso-thread > h4").textContent = Mark.up("{{ i18n-no-comments }}"); diff --git a/isso/utils/parse.py b/isso/utils/parse.py index a03ba7b..7ed2711 100644 --- a/isso/utils/parse.py +++ b/isso/utils/parse.py @@ -76,14 +76,14 @@ def host(name): return (rv.netloc.rsplit(':')[0], rv.port or 80, rv.scheme == 'https') -def title(data, default=u"Untitled."): +def thread(data, default=u"Untitled.", id=None): """ Extract

title from web page. The title is *probably* the text node, which is the nearest H1 node in context to an element with the `isso-thread` id. - >>> title("asdf") # doctest: +IGNORE_UNICODE - 'Untitled.' - >>> title(''' + >>> thread("asdf") # doctest: +IGNORE_UNICODE + (None, 'Untitled.') + >>> thread(''' ... ... ... Foo! @@ -102,14 +102,22 @@ def title(data, default=u"Untitled."): ... ... ... ''') # doctest: +IGNORE_UNICODE - 'Can you find me?' - >>> title(''' + (None, 'Can you find me?') + >>> thread(''' ... ... ...

I'm the real title!1 ...
... ''') # doctest: +IGNORE_UNICODE - 'No way!' + (None, 'No way!') + >>> thread(''' + ...
+ ... ''') # doctest: +IGNORE_UNICODE + ('test', 'Test') + >>> thread(''' + ...
+ ... ''') # doctest: +IGNORE_UNICODE + ('Fuu.', 'Untitled.') """ html = html5lib.parse(data, treebuilder="dom") @@ -123,7 +131,7 @@ def title(data, default=u"Untitled."): chain(*map(html.getElementsByTagName, ("div", "section")))))) if not el: - return default + return id, default el = el[0] visited = [] @@ -146,7 +154,12 @@ def title(data, default=u"Untitled."): yield item try: - return unquote(el.attributes["data-title"].value) + id = unquote(el.attributes["data-isso-id"].value) + except (KeyError, AttributeError): + pass + + try: + return id, unquote(el.attributes["data-title"].value) except (KeyError, AttributeError): pass @@ -156,8 +169,8 @@ def title(data, default=u"Untitled."): rv = recurse(el) if rv: - return ''.join(gettext(rv)).strip() + return id, ''.join(gettext(rv)).strip() el = el.parentNode - return default + return id, default diff --git a/isso/views/comments.py b/isso/views/comments.py index 76c70eb..4d8183a 100644 --- a/isso/views/comments.py +++ b/isso/views/comments.py @@ -142,7 +142,7 @@ class API(object): if uri not in self.threads: with http.curl('GET', local("origin"), uri) as resp: if resp and resp.status == 200: - title = parse.title(resp.read()) + uri, title = parse.thread(resp.read(), id=uri) else: return NotFound('URI does not exist')