forked from sch/Blasta
CSS : Modify stylesheet due to modifying XHTML;
Python : Improve editing of tags; Python : Fix error upon no results on Atom; SQLite : Add triggers to count instances of entries; SQLite : Add triggers to delete entries SQLite : Add triggers to delete tags; XSLT : Remove control characters in favour of nbsp entity; XSLT : Improve links and design; XHTML : Add a new document about folksonomy; XHTML : Add a new template for URL; XHTML : Add indicators.
This commit is contained in:
parent
164b4d67d4
commit
a53c3a3436
34 changed files with 926 additions and 100 deletions
288
blasta.py
288
blasta.py
|
@ -491,6 +491,18 @@ class HttpInstance:
|
||||||
response.headers["Content-Type"] = "application/xhtml+xml"
|
response.headers["Content-Type"] = "application/xhtml+xml"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@self.app.get('/help/about/folksonomy')
|
||||||
|
def help_about_folksonomies_get(request: Request):
|
||||||
|
jabber_id = Utilities.is_jid_matches_to_session(accounts, sessions, request)
|
||||||
|
template_file = 'folksonomy.xhtml'
|
||||||
|
template_dict = {
|
||||||
|
'request' : request,
|
||||||
|
'jabber_id' : jabber_id,
|
||||||
|
'journal' : journal}
|
||||||
|
response = templates.TemplateResponse(template_file, template_dict)
|
||||||
|
response.headers["Content-Type"] = "application/xhtml+xml"
|
||||||
|
return response
|
||||||
|
|
||||||
@self.app.get('/help/about/ideas')
|
@self.app.get('/help/about/ideas')
|
||||||
def help_about_ideas_get(request: Request):
|
def help_about_ideas_get(request: Request):
|
||||||
jabber_id = Utilities.is_jid_matches_to_session(accounts, sessions, request)
|
jabber_id = Utilities.is_jid_matches_to_session(accounts, sessions, request)
|
||||||
|
@ -849,6 +861,11 @@ class HttpInstance:
|
||||||
entries_count = SQLite.get_entries_count_by_jid(db_file, jid)
|
entries_count = SQLite.get_entries_count_by_jid(db_file, jid)
|
||||||
for tag, instances in SQLite.get_30_tags_by_jid(db_file, jid, index_first):
|
for tag, instances in SQLite.get_30_tags_by_jid(db_file, jid, index_first):
|
||||||
tags_dict[tag] = instances
|
tags_dict[tag] = instances
|
||||||
|
if not entries_database:
|
||||||
|
message = 'Blasta system message » Error: No entries were found.'
|
||||||
|
description = 'No results'
|
||||||
|
path = 'error'
|
||||||
|
return result_post(request, jabber_id, description, message, path)
|
||||||
if entries_count:
|
if entries_count:
|
||||||
entries = []
|
entries = []
|
||||||
for entry in entries_database:
|
for entry in entries_database:
|
||||||
|
@ -856,6 +873,8 @@ class HttpInstance:
|
||||||
for tag in SQLite.get_tags_by_entry_id(db_file, entry[0]):
|
for tag in SQLite.get_tags_by_entry_id(db_file, entry[0]):
|
||||||
tags_sorted.append(tag[0])
|
tags_sorted.append(tag[0])
|
||||||
entry_jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
entry_jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
||||||
|
url_hash = Utilities.hash_url_to_md5(entry[2])
|
||||||
|
instances = SQLite.get_entry_instances_by_url_hash(db_file, url_hash)
|
||||||
entries.append(
|
entries.append(
|
||||||
{'title' : entry[3],
|
{'title' : entry[3],
|
||||||
'link' : entry[2],
|
'link' : entry[2],
|
||||||
|
@ -863,10 +882,10 @@ class HttpInstance:
|
||||||
'published' : entry[6],
|
'published' : entry[6],
|
||||||
'updated' : entry[7],
|
'updated' : entry[7],
|
||||||
'tags' : tags_sorted,
|
'tags' : tags_sorted,
|
||||||
'url_hash' : Utilities.hash_url_to_md5(entry[2]), #entry[1]
|
'url_hash' : url_hash,
|
||||||
'jid' : entry_jid,
|
'jid' : entry_jid,
|
||||||
'name' : entry_jid, # jid.split('@')[0] if '@' in jid else jid,
|
'name' : entry_jid, # jid.split('@')[0] if '@' in jid else jid,
|
||||||
'instances' : entry[8]})
|
'instances' : instances})
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
try:
|
try:
|
||||||
date_iso = entry['published']
|
date_iso = entry['published']
|
||||||
|
@ -985,6 +1004,7 @@ class HttpInstance:
|
||||||
'jid': jid,
|
'jid': jid,
|
||||||
'journal': journal,
|
'journal': journal,
|
||||||
'message': message,
|
'message': message,
|
||||||
|
'node_type': node_type,
|
||||||
'page_next': page_next,
|
'page_next': page_next,
|
||||||
'page_prev': page_prev,
|
'page_prev': page_prev,
|
||||||
'pager' : True,
|
'pager' : True,
|
||||||
|
@ -1095,6 +1115,11 @@ class HttpInstance:
|
||||||
entries_database = SQLite.get_entries_recent(db_file, index_first)
|
entries_database = SQLite.get_entries_recent(db_file, index_first)
|
||||||
tags_of_entries = SQLite.get_30_tags_by_entries_recent(db_file, index_first)
|
tags_of_entries = SQLite.get_30_tags_by_entries_recent(db_file, index_first)
|
||||||
entries_count = SQLite.get_entries_count(db_file)
|
entries_count = SQLite.get_entries_count(db_file)
|
||||||
|
if not entries_database:
|
||||||
|
message = 'Blasta system message » Error: No entries were found.'
|
||||||
|
description = 'No results'
|
||||||
|
path = 'error'
|
||||||
|
return result_post(request, jabber_id, description, message, path)
|
||||||
tags_dict = {}
|
tags_dict = {}
|
||||||
#for tag, instances in SQLite.get_tags_30(db_file):
|
#for tag, instances in SQLite.get_tags_30(db_file):
|
||||||
for tag, instances in tags_of_entries:
|
for tag, instances in tags_of_entries:
|
||||||
|
@ -1105,6 +1130,8 @@ class HttpInstance:
|
||||||
for tag in SQLite.get_tags_by_entry_id(db_file, entry[0]):
|
for tag in SQLite.get_tags_by_entry_id(db_file, entry[0]):
|
||||||
tags_sorted.append(tag[0])
|
tags_sorted.append(tag[0])
|
||||||
jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
||||||
|
url_hash = Utilities.hash_url_to_md5(entry[2])
|
||||||
|
instances = SQLite.get_entry_instances_by_url_hash(db_file, url_hash)
|
||||||
entries.append(
|
entries.append(
|
||||||
{'title' : entry[3],
|
{'title' : entry[3],
|
||||||
'link' : entry[2],
|
'link' : entry[2],
|
||||||
|
@ -1112,10 +1139,10 @@ class HttpInstance:
|
||||||
'published' : entry[6],
|
'published' : entry[6],
|
||||||
'updated' : entry[7],
|
'updated' : entry[7],
|
||||||
'tags' : tags_sorted,
|
'tags' : tags_sorted,
|
||||||
'url_hash' : Utilities.hash_url_to_md5(entry[2]), #entry[1]
|
'url_hash' : url_hash, #entry[1]
|
||||||
'jid' : jid,
|
'jid' : jid,
|
||||||
'name' : jid, # jid.split('@')[0] if '@' in jid else jid,
|
'name' : jid, # jid.split('@')[0] if '@' in jid else jid,
|
||||||
'instances' : entry[8]})
|
'instances' : instances})
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
try:
|
try:
|
||||||
date_iso = entry['published']
|
date_iso = entry['published']
|
||||||
|
@ -1139,7 +1166,6 @@ class HttpInstance:
|
||||||
message = ('Welcome to Blasta, an XMPP PubSub oriented social '
|
message = ('Welcome to Blasta, an XMPP PubSub oriented social '
|
||||||
'bookmarks manager for organizing online content.')
|
'bookmarks manager for organizing online content.')
|
||||||
message_link = {'href' : '/help/about', 'text' : 'Learn more'}
|
message_link = {'href' : '/help/about', 'text' : 'Learn more'}
|
||||||
template_file = 'browse.xhtml'
|
|
||||||
template_dict = {
|
template_dict = {
|
||||||
'request' : request,
|
'request' : request,
|
||||||
'description' : description,
|
'description' : description,
|
||||||
|
@ -1151,6 +1177,7 @@ class HttpInstance:
|
||||||
'node_id' : node_id,
|
'node_id' : node_id,
|
||||||
'page_next' : page_next,
|
'page_next' : page_next,
|
||||||
'page_prev' : page_prev,
|
'page_prev' : page_prev,
|
||||||
|
'page_type' : page_type,
|
||||||
'pager' : True,
|
'pager' : True,
|
||||||
'param_query' : param_query,
|
'param_query' : param_query,
|
||||||
'param_tags' : param_tags,
|
'param_tags' : param_tags,
|
||||||
|
@ -1159,6 +1186,8 @@ class HttpInstance:
|
||||||
'syndicate' : syndicate,
|
'syndicate' : syndicate,
|
||||||
'tags' : tags_dict}
|
'tags' : tags_dict}
|
||||||
if param_mode == 'feed':
|
if param_mode == 'feed':
|
||||||
|
# NOTE Consider scheme "feed" in order to prompt news
|
||||||
|
# reader 'feed://' + request.url.netloc + request.url.path
|
||||||
template_file = 'browse.atom'
|
template_file = 'browse.atom'
|
||||||
response = templates.TemplateResponse(template_file, template_dict)
|
response = templates.TemplateResponse(template_file, template_dict)
|
||||||
response.headers["Content-Type"] = "application/xml"
|
response.headers["Content-Type"] = "application/xml"
|
||||||
|
@ -1507,7 +1536,6 @@ class HttpInstance:
|
||||||
'jid' : jabber_id,
|
'jid' : jabber_id,
|
||||||
'name' : name,
|
'name' : name,
|
||||||
'instances' : instances}
|
'instances' : instances}
|
||||||
#message = 'Discover new links and see who shares them'
|
|
||||||
xmpp_instance = accounts[jabber_id]
|
xmpp_instance = accounts[jabber_id]
|
||||||
payload = Syndication.create_rfc4287_entry(entry_new)
|
payload = Syndication.create_rfc4287_entry(entry_new)
|
||||||
iq = await XmppPubsub.publish_node_item(
|
iq = await XmppPubsub.publish_node_item(
|
||||||
|
@ -1556,12 +1584,19 @@ class HttpInstance:
|
||||||
param_tags = request.query_params.get('tags', '')
|
param_tags = request.query_params.get('tags', '')
|
||||||
param_summary = request.query_params.get('summary', '')
|
param_summary = request.query_params.get('summary', '')
|
||||||
path = 'save'
|
path = 'save'
|
||||||
|
if request.query_params:
|
||||||
|
message = message_link = None
|
||||||
|
else:
|
||||||
|
message = 'For greater ease, you migh want to try our'
|
||||||
|
message_link = {'href' : '/help/utilities#buttons', 'text' : 'bookmarklets'}
|
||||||
template_file = 'edit.xhtml'
|
template_file = 'edit.xhtml'
|
||||||
template_dict = {
|
template_dict = {
|
||||||
'request' : request,
|
'request' : request,
|
||||||
'description' : description,
|
'description' : description,
|
||||||
'jabber_id' : jabber_id,
|
'jabber_id' : jabber_id,
|
||||||
'journal' : journal,
|
'journal' : journal,
|
||||||
|
'message' : message,
|
||||||
|
'message_link' : message_link,
|
||||||
'path' : path,
|
'path' : path,
|
||||||
'routine' : routine,
|
'routine' : routine,
|
||||||
'summary' : param_summary,
|
'summary' : param_summary,
|
||||||
|
@ -1873,7 +1908,7 @@ class HttpInstance:
|
||||||
entries.append(entry)
|
entries.append(entry)
|
||||||
tags_list = {}
|
tags_list = {}
|
||||||
tags_and_instances = SQLite.get_tags_and_instances_by_url_hash(db_file, url_hash)
|
tags_and_instances = SQLite.get_tags_and_instances_by_url_hash(db_file, url_hash)
|
||||||
for tag, instances in tags_and_instances: tags_list[tag] = instances
|
for tag, tag_instances in tags_and_instances: tags_list[tag] = tag_instances
|
||||||
else: # NOTE Is it possible to activate this else statement? Consider removal.
|
else: # NOTE Is it possible to activate this else statement? Consider removal.
|
||||||
# https://fastapi.tiangolo.com/tutorial/handling-errors/
|
# https://fastapi.tiangolo.com/tutorial/handling-errors/
|
||||||
#raise HTTPException(status_code=404, detail="Item not found")
|
#raise HTTPException(status_code=404, detail="Item not found")
|
||||||
|
@ -1890,8 +1925,9 @@ class HttpInstance:
|
||||||
tags_sorted.append(tag[0])
|
tags_sorted.append(tag[0])
|
||||||
tags_list = {}
|
tags_list = {}
|
||||||
tags_and_instances = SQLite.get_tags_and_instances_by_entry_id(db_file, entry[0])
|
tags_and_instances = SQLite.get_tags_and_instances_by_entry_id(db_file, entry[0])
|
||||||
for tag, instances in tags_and_instances: tags_list[tag] = instances
|
for tag, tag_instances in tags_and_instances: tags_list[tag] = tag_instances
|
||||||
jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
||||||
|
instances = SQLite.get_entry_instances_by_url_hash(db_file, url_hash)
|
||||||
entries.append(
|
entries.append(
|
||||||
{'title' : entry[3],
|
{'title' : entry[3],
|
||||||
'link' : entry[2],
|
'link' : entry[2],
|
||||||
|
@ -1900,10 +1936,10 @@ class HttpInstance:
|
||||||
'published_mod' : Utilities.convert_iso8601_to_readable(entry[6]),
|
'published_mod' : Utilities.convert_iso8601_to_readable(entry[6]),
|
||||||
'updated' : entry[7],
|
'updated' : entry[7],
|
||||||
'tags' : tags_sorted,
|
'tags' : tags_sorted,
|
||||||
'url_hash' : entry[1], # Utilities.hash_url_to_md5(entry[2])
|
'url_hash' : url_hash,
|
||||||
'jid' : jid,
|
'jid' : jid,
|
||||||
'name' : jid, # jid.split('@')[0] if '@' in jid else jid,
|
'name' : jid, # jid.split('@')[0] if '@' in jid else jid,
|
||||||
'instances' : entry[8]})
|
'instances' : instances})
|
||||||
# message = 'XMPP system message » {}.'.format(iq)
|
# message = 'XMPP system message » {}.'.format(iq)
|
||||||
# if iq == 'Node not found':
|
# if iq == 'Node not found':
|
||||||
# description = 'An error has occurred'
|
# description = 'An error has occurred'
|
||||||
|
@ -1925,8 +1961,9 @@ class HttpInstance:
|
||||||
tags_sorted.append(tag[0])
|
tags_sorted.append(tag[0])
|
||||||
tags_list = {}
|
tags_list = {}
|
||||||
tags_and_instances = SQLite.get_tags_and_instances_by_entry_id(db_file, entry[0])
|
tags_and_instances = SQLite.get_tags_and_instances_by_entry_id(db_file, entry[0])
|
||||||
for tag, instances in tags_and_instances: tags_list[tag] = instances
|
for tag, tag_instances in tags_and_instances: tags_list[tag] = tag_instances
|
||||||
jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
jid = SQLite.get_jid_by_jid_id(db_file, entry[5])
|
||||||
|
instances = SQLite.get_entry_instances_by_url_hash(db_file, url_hash)
|
||||||
entries.append(
|
entries.append(
|
||||||
{'title' : entry[3],
|
{'title' : entry[3],
|
||||||
'link' : entry[2],
|
'link' : entry[2],
|
||||||
|
@ -1935,10 +1972,10 @@ class HttpInstance:
|
||||||
'published_mod' : Utilities.convert_iso8601_to_readable(entry[6]),
|
'published_mod' : Utilities.convert_iso8601_to_readable(entry[6]),
|
||||||
'updated' : entry[7],
|
'updated' : entry[7],
|
||||||
'tags' : tags_sorted,
|
'tags' : tags_sorted,
|
||||||
'url_hash' : entry[1], # Utilities.hash_url_to_md5(entry[2])
|
'url_hash' : url_hash,
|
||||||
'jid' : jid,
|
'jid' : jid,
|
||||||
'name' : jid, # jid.split('@')[0] if '@' in jid else jid,
|
'name' : jid, # jid.split('@')[0] if '@' in jid else jid,
|
||||||
'instances' : entry[8]})
|
'instances' : instances})
|
||||||
else:
|
else:
|
||||||
# https://fastapi.tiangolo.com/tutorial/handling-errors/
|
# https://fastapi.tiangolo.com/tutorial/handling-errors/
|
||||||
#raise HTTPException(status_code=404, detail="Item not found")
|
#raise HTTPException(status_code=404, detail="Item not found")
|
||||||
|
@ -1946,9 +1983,21 @@ class HttpInstance:
|
||||||
description = 'The requested bookmark does not exist'
|
description = 'The requested bookmark does not exist'
|
||||||
path = 'error'
|
path = 'error'
|
||||||
return result_post(request, jabber_id, description, message, path)
|
return result_post(request, jabber_id, description, message, path)
|
||||||
message = 'Information for URL {}'.format(entries[0]['link']) # entry[2]
|
message = 'Information for URI {}'.format(entries[0]['link']) # entry[2]
|
||||||
description = 'Discover new links and see who shares them'
|
if instances > 1:
|
||||||
template_file = 'browse.xhtml'
|
description = 'Discover new resources and see who shares them'
|
||||||
|
template_file = 'people.xhtml'
|
||||||
|
people_list = {}
|
||||||
|
jids_and_tags = SQLite.get_jids_and_tags_by_url_hash(db_file, url_hash)
|
||||||
|
for jid, tag in jids_and_tags:
|
||||||
|
if jid in people_list and isinstance(people_list[jid], list):
|
||||||
|
people_list[jid].append(tag)
|
||||||
|
else:
|
||||||
|
people_list[jid] = [tag]
|
||||||
|
else:
|
||||||
|
people_list = None
|
||||||
|
description = 'Resource properties'
|
||||||
|
template_file = 'browse.xhtml'
|
||||||
template_dict = {
|
template_dict = {
|
||||||
'request' : request,
|
'request' : request,
|
||||||
'description' : description,
|
'description' : description,
|
||||||
|
@ -1960,6 +2009,7 @@ class HttpInstance:
|
||||||
'node_id' : node_id,
|
'node_id' : node_id,
|
||||||
'param_hash' : param_hash,
|
'param_hash' : param_hash,
|
||||||
'path' : path,
|
'path' : path,
|
||||||
|
'people' : people_list,
|
||||||
'pubsub_jid' : jabber_id_pubsub,
|
'pubsub_jid' : jabber_id_pubsub,
|
||||||
'syndicate' : syndicate,
|
'syndicate' : syndicate,
|
||||||
'tags' : tags_list}
|
'tags' : tags_list}
|
||||||
|
@ -2069,16 +2119,19 @@ class HttpInstance:
|
||||||
tags_invalid = []
|
tags_invalid = []
|
||||||
#tags_list_new = tags.split(',')
|
#tags_list_new = tags.split(',')
|
||||||
tags_list_new = tags_new
|
tags_list_new = tags_new
|
||||||
tags_list_old = tags_old.split(',')
|
tags_list_old = tags_old.split(', ')
|
||||||
for tag in tags_list_old:
|
for tag in tags_list_old:
|
||||||
|
tag_trim = tag.strip()
|
||||||
if tag not in tags_list_new:
|
if tag not in tags_list_new:
|
||||||
tags_invalid.append(tag)
|
tags_invalid.append(tag_trim)
|
||||||
for tag in tags_list_new:
|
for tag in tags_list_new:
|
||||||
if tag not in tags_list_old:
|
if tag:
|
||||||
tags_valid.append(tag)
|
tag_trim = tag.strip()
|
||||||
# FIXME Variable tags_valid is not in use.
|
if tag_trim not in tags_list_old:
|
||||||
# NOTE Variable tags_valid might not be needed. See function associate_entries_tags_jids.
|
tags_valid.append(tag_trim)
|
||||||
await SQLite.delete_combination_row_by_entry_id_and_tag_id_and_jid_id(db_file, url_hash, tags_invalid, jabber_id)
|
# FIXME Variable tags_valid is not in use.
|
||||||
|
# NOTE Variable tags_valid might not be needed. See function associate_entries_tags_jids.
|
||||||
|
entry['tags'] = tags_valid
|
||||||
await SQLite.add_tags(db_file, [entry])
|
await SQLite.add_tags(db_file, [entry])
|
||||||
# Slow (high I/O)
|
# Slow (high I/O)
|
||||||
entry_id = SQLite.get_entry_id_by_url_hash(db_file, url_hash)
|
entry_id = SQLite.get_entry_id_by_url_hash(db_file, url_hash)
|
||||||
|
@ -2089,6 +2142,17 @@ class HttpInstance:
|
||||||
# await SQLite.associate_entries_tags_jids(db_file, entry)
|
# await SQLite.associate_entries_tags_jids(db_file, entry)
|
||||||
else:
|
else:
|
||||||
await SQLite.associate_entries_tags_jids(db_file, entry)
|
await SQLite.associate_entries_tags_jids(db_file, entry)
|
||||||
|
print('tags_new')
|
||||||
|
print(tags_new)
|
||||||
|
print('tags_old')
|
||||||
|
print(tags_old)
|
||||||
|
print('tags_valid')
|
||||||
|
print(tags_valid)
|
||||||
|
print('tags_invalid')
|
||||||
|
print(tags_invalid)
|
||||||
|
print(url_hash)
|
||||||
|
print(jabber_id)
|
||||||
|
await SQLite.delete_combination_row_by_url_hash_and_tag_and_jid(db_file, url_hash, tags_invalid, jabber_id)
|
||||||
# Entry for HTML
|
# Entry for HTML
|
||||||
entry['published_mod'] = Utilities.convert_iso8601_to_readable(published)
|
entry['published_mod'] = Utilities.convert_iso8601_to_readable(published)
|
||||||
entry['updated_mod'] = Utilities.convert_iso8601_to_readable(timestamp)
|
entry['updated_mod'] = Utilities.convert_iso8601_to_readable(timestamp)
|
||||||
|
@ -2250,7 +2314,7 @@ class HttpInstance:
|
||||||
|
|
||||||
# Remove the item association from database
|
# Remove the item association from database
|
||||||
await SQLite.delete_combination_row_by_jid_and_url_hash(db_file, url_hash, jabber_id)
|
await SQLite.delete_combination_row_by_jid_and_url_hash(db_file, url_hash, jabber_id)
|
||||||
#await SQLite.delete_combination_row_by_entry_id_and_tag_id_and_jid_id(db_file, url_hash, entry['tags'], jabber_id)
|
#await SQLite.delete_combination_row_by_url_hash_and_tag_and_jid(db_file, url_hash, entry['tags'], jabber_id)
|
||||||
|
|
||||||
# Remove the item from cache
|
# Remove the item from cache
|
||||||
Data.remove_item_from_cache(jabber_id, node_type, url_hash)
|
Data.remove_item_from_cache(jabber_id, node_type, url_hash)
|
||||||
|
@ -2323,6 +2387,8 @@ class HttpInstance:
|
||||||
description = 'Edit an existing bookmark'
|
description = 'Edit an existing bookmark'
|
||||||
entry = Syndication.extract_items(item_payload)
|
entry = Syndication.extract_items(item_payload)
|
||||||
entry['instances'] = SQLite.get_entry_instances_by_url_hash(db_file, url_hash)
|
entry['instances'] = SQLite.get_entry_instances_by_url_hash(db_file, url_hash)
|
||||||
|
print(jabber_id)
|
||||||
|
print(entry['tags'])
|
||||||
else:
|
else:
|
||||||
# TODO Consider redirect to path /save (function save_get)
|
# TODO Consider redirect to path /save (function save_get)
|
||||||
# NOTE This seems to be the best to do, albeit, perhaps the pathname should be /save instead of /url/hash/edit.
|
# NOTE This seems to be the best to do, albeit, perhaps the pathname should be /save instead of /url/hash/edit.
|
||||||
|
@ -2338,8 +2404,8 @@ class HttpInstance:
|
||||||
'summary' : result[4],
|
'summary' : result[4],
|
||||||
'published' : result[6],
|
'published' : result[6],
|
||||||
'updated' : result[7],
|
'updated' : result[7],
|
||||||
'tags' : tags_sorted,
|
'tags' : tags_sorted}
|
||||||
'instances' : result[8]}
|
#'instances' : result[8],
|
||||||
#'jid' = jabber_id,
|
#'jid' = jabber_id,
|
||||||
#'name' : name,
|
#'name' : name,
|
||||||
#'url_hash' : url_hash
|
#'url_hash' : url_hash
|
||||||
|
@ -2347,6 +2413,14 @@ class HttpInstance:
|
||||||
entry['jid'] = jabber_id
|
entry['jid'] = jabber_id
|
||||||
entry['name'] = name
|
entry['name'] = name
|
||||||
entry['url_hash'] = url_hash
|
entry['url_hash'] = url_hash
|
||||||
|
else:
|
||||||
|
message = 'XMPP system message » {}.'.format(iq)
|
||||||
|
if iq == 'Node not found':
|
||||||
|
description = 'An error has occurred'
|
||||||
|
else:
|
||||||
|
description = 'An unknown error has occurred'
|
||||||
|
path = 'error'
|
||||||
|
return result_post(request, jabber_id, description, message, path)
|
||||||
template_file = 'edit.xhtml'
|
template_file = 'edit.xhtml'
|
||||||
template_dict = {
|
template_dict = {
|
||||||
'request' : request,
|
'request' : request,
|
||||||
|
@ -2543,6 +2617,64 @@ class SQLite:
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
sql_trigger_instances_entry_decrease = (
|
||||||
|
"""
|
||||||
|
CREATE TRIGGER instances_entry_decrease
|
||||||
|
AFTER DELETE ON combination_entries_tags_jids
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE main_entries
|
||||||
|
SET instances = (
|
||||||
|
SELECT COUNT(DISTINCT jid_id)
|
||||||
|
FROM combination_entries_tags_jids
|
||||||
|
WHERE entry_id = OLD.entry_id
|
||||||
|
)
|
||||||
|
WHERE id = OLD.entry_id;
|
||||||
|
END;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
sql_trigger_instances_entry_increase = (
|
||||||
|
"""
|
||||||
|
CREATE TRIGGER instances_entry_increase
|
||||||
|
AFTER INSERT ON combination_entries_tags_jids
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE main_entries
|
||||||
|
SET instances = (
|
||||||
|
SELECT COUNT(DISTINCT jid_id)
|
||||||
|
FROM combination_entries_tags_jids
|
||||||
|
WHERE entry_id = NEW.entry_id
|
||||||
|
)
|
||||||
|
WHERE id = NEW.entry_id;
|
||||||
|
END;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
sql_trigger_instances_entry_update = (
|
||||||
|
"""
|
||||||
|
CREATE TRIGGER instances_entry_update
|
||||||
|
AFTER UPDATE ON combination_entries_tags_jids
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
-- Decrease instances for the old tag_id
|
||||||
|
UPDATE main_entries
|
||||||
|
SET instances = (
|
||||||
|
SELECT COUNT(DISTINCT jid_id)
|
||||||
|
FROM combination_entries_tags_jids
|
||||||
|
WHERE entry_id = OLD.entry_id
|
||||||
|
)
|
||||||
|
WHERE id = OLD.entry_id;
|
||||||
|
|
||||||
|
-- Increase instances for the new tag_id
|
||||||
|
UPDATE main_entries
|
||||||
|
SET instances = (
|
||||||
|
SELECT COUNT(DISTINCT jid_id)
|
||||||
|
FROM combination_entries_tags_jids
|
||||||
|
WHERE entry_id = NEW.entry_id
|
||||||
|
)
|
||||||
|
WHERE id = NEW.entry_id;
|
||||||
|
END;
|
||||||
|
"""
|
||||||
|
)
|
||||||
sql_trigger_instances_tag_decrease = (
|
sql_trigger_instances_tag_decrease = (
|
||||||
"""
|
"""
|
||||||
CREATE TRIGGER instances_tag_decrease
|
CREATE TRIGGER instances_tag_decrease
|
||||||
|
@ -2643,6 +2775,17 @@ class SQLite:
|
||||||
END;
|
END;
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
sql_trigger_entry_remove = (
|
||||||
|
"""
|
||||||
|
CREATE TRIGGER entry_remove
|
||||||
|
AFTER UPDATE ON main_entries
|
||||||
|
FOR EACH ROW
|
||||||
|
WHEN NEW.instances < 1
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM main_entries WHERE id = OLD.id;
|
||||||
|
END;
|
||||||
|
"""
|
||||||
|
)
|
||||||
sql_trigger_jid_count_increase = (
|
sql_trigger_jid_count_increase = (
|
||||||
"""
|
"""
|
||||||
CREATE TRIGGER jid_count_increase
|
CREATE TRIGGER jid_count_increase
|
||||||
|
@ -2727,6 +2870,17 @@ class SQLite:
|
||||||
END;
|
END;
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
sql_trigger_tag_remove = (
|
||||||
|
"""
|
||||||
|
CREATE TRIGGER tag_remove
|
||||||
|
AFTER UPDATE ON main_tags
|
||||||
|
FOR EACH ROW
|
||||||
|
WHEN NEW.instances < 1
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM main_tags WHERE id = OLD.id;
|
||||||
|
END;
|
||||||
|
"""
|
||||||
|
)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute(sql_table_main_entries)
|
cur.execute(sql_table_main_entries)
|
||||||
cur.execute(sql_table_main_jids)
|
cur.execute(sql_table_main_jids)
|
||||||
|
@ -2736,18 +2890,23 @@ class SQLite:
|
||||||
cur.execute(sql_table_authorization_entries_jids)
|
cur.execute(sql_table_authorization_entries_jids)
|
||||||
cur.execute(sql_table_report_entries)
|
cur.execute(sql_table_report_entries)
|
||||||
cur.execute(sql_table_report_jids)
|
cur.execute(sql_table_report_jids)
|
||||||
|
cur.execute(sql_trigger_instances_entry_decrease)
|
||||||
|
cur.execute(sql_trigger_instances_entry_increase)
|
||||||
|
cur.execute(sql_trigger_instances_entry_update)
|
||||||
cur.execute(sql_trigger_instances_tag_decrease)
|
cur.execute(sql_trigger_instances_tag_decrease)
|
||||||
cur.execute(sql_trigger_instances_tag_increase)
|
cur.execute(sql_trigger_instances_tag_increase)
|
||||||
cur.execute(sql_trigger_instances_tag_update)
|
cur.execute(sql_trigger_instances_tag_update)
|
||||||
cur.execute(sql_trigger_entry_count_increase)
|
cur.execute(sql_trigger_entry_count_increase)
|
||||||
cur.execute(sql_trigger_entry_count_decrease)
|
cur.execute(sql_trigger_entry_count_decrease)
|
||||||
cur.execute(sql_trigger_entry_count_update)
|
cur.execute(sql_trigger_entry_count_update)
|
||||||
|
cur.execute(sql_trigger_entry_remove)
|
||||||
cur.execute(sql_trigger_jid_count_increase)
|
cur.execute(sql_trigger_jid_count_increase)
|
||||||
cur.execute(sql_trigger_jid_count_decrease)
|
cur.execute(sql_trigger_jid_count_decrease)
|
||||||
cur.execute(sql_trigger_jid_count_update)
|
cur.execute(sql_trigger_jid_count_update)
|
||||||
cur.execute(sql_trigger_tag_count_increase)
|
cur.execute(sql_trigger_tag_count_increase)
|
||||||
cur.execute(sql_trigger_tag_count_decrease)
|
cur.execute(sql_trigger_tag_count_decrease)
|
||||||
cur.execute(sql_trigger_tag_count_update)
|
cur.execute(sql_trigger_tag_count_update)
|
||||||
|
cur.execute(sql_trigger_tag_remove)
|
||||||
|
|
||||||
def add_statistics(db_file):
|
def add_statistics(db_file):
|
||||||
"""
|
"""
|
||||||
|
@ -3022,7 +3181,7 @@ class SQLite:
|
||||||
result = cur.execute(sql, par).fetchone()
|
result = cur.execute(sql, par).fetchone()
|
||||||
return result[0] if result and len(result) == 1 else result
|
return result[0] if result and len(result) == 1 else result
|
||||||
|
|
||||||
async def delete_combination_row_by_entry_id_and_tag_id_and_jid_id(db_file, url_hash, tags, jid):
|
async def delete_combination_row_by_url_hash_and_tag_and_jid(db_file, url_hash, tags, jid):
|
||||||
"""
|
"""
|
||||||
Delete a row by a given entry ID and a given Jabber ID and given tags.
|
Delete a row by a given entry ID and a given Jabber ID and given tags.
|
||||||
|
|
||||||
|
@ -3042,8 +3201,8 @@ class SQLite:
|
||||||
None.
|
None.
|
||||||
"""
|
"""
|
||||||
function_name = sys._getframe().f_code.co_name
|
function_name = sys._getframe().f_code.co_name
|
||||||
# logger.debug('{}: db_file: {} entry_id: {} tag_id: {} jid_id: {}'
|
# logger.debug('{}: db_file: {} url_hash: {} tag_id: {} jid_id: {}'
|
||||||
# .format(function_name, db_file, entry_id, tag_id, jid_id))
|
# .format(function_name, db_file, url_hash, tag_id, jid_id))
|
||||||
sql = (
|
sql = (
|
||||||
"""
|
"""
|
||||||
DELETE
|
DELETE
|
||||||
|
@ -3168,6 +3327,77 @@ class SQLite:
|
||||||
result = cur.execute(sql, par).fetchall()
|
result = cur.execute(sql, par).fetchall()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_jids_and_tags_by_entry_id(db_file, entry_id):
|
||||||
|
"""
|
||||||
|
Get JIDs and tags by a given ID entry.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
db_file : str
|
||||||
|
Path to database file.
|
||||||
|
entry_id : str
|
||||||
|
An ID of an entry.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
result : tuple
|
||||||
|
JIDs and tags.
|
||||||
|
"""
|
||||||
|
function_name = sys._getframe().f_code.co_name
|
||||||
|
# logger.debug('{}: db_file: {} index_first: {}'
|
||||||
|
# .format(function_name, db_file, index_first))
|
||||||
|
sql = (
|
||||||
|
"""
|
||||||
|
SELECT main_jids.jid, main_tags.tag
|
||||||
|
FROM main_tags
|
||||||
|
INNER JOIN combination_entries_tags_jids ON main_tags.id = combination_entries_tags_jids.tag_id
|
||||||
|
INNER JOIN main_jids ON main_jids.id = combination_entries_tags_jids.jid_id
|
||||||
|
WHERE combination_entries_tags_jids.entry_id = ?
|
||||||
|
ORDER BY main_tags.instances DESC;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
par = (entry_id,)
|
||||||
|
with SQLite.create_connection(db_file) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
|
result = cur.execute(sql, par).fetchall()
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_jids_and_tags_by_url_hash(db_file, url_hash):
|
||||||
|
"""
|
||||||
|
Get JIDs and tags by a given URI hash.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
db_file : str
|
||||||
|
Path to database file.
|
||||||
|
url_hash : str
|
||||||
|
A URL hash of an entry.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
result : tuple
|
||||||
|
JIDs and tags.
|
||||||
|
"""
|
||||||
|
function_name = sys._getframe().f_code.co_name
|
||||||
|
# logger.debug('{}: db_file: {} index_first: {}'
|
||||||
|
# .format(function_name, db_file, index_first))
|
||||||
|
sql = (
|
||||||
|
"""
|
||||||
|
SELECT main_jids.jid, main_tags.tag
|
||||||
|
FROM main_tags
|
||||||
|
INNER JOIN combination_entries_tags_jids ON main_tags.id = combination_entries_tags_jids.tag_id
|
||||||
|
INNER JOIN main_jids ON main_jids.id = combination_entries_tags_jids.jid_id
|
||||||
|
INNER JOIN main_entries ON main_entries.id = combination_entries_tags_jids.entry_id
|
||||||
|
WHERE main_entries.url_hash = ?
|
||||||
|
ORDER BY main_tags.instances DESC;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
par = (url_hash,)
|
||||||
|
with SQLite.create_connection(db_file) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
|
result = cur.execute(sql, par).fetchall()
|
||||||
|
return result
|
||||||
|
|
||||||
def get_tag_id_by_tag(db_file, tag):
|
def get_tag_id_by_tag(db_file, tag):
|
||||||
"""
|
"""
|
||||||
Get a tag ID by a given tag.
|
Get a tag ID by a given tag.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# Contact
|
# Contact
|
||||||
[contacts]
|
[contacts]
|
||||||
email = ""
|
email = ""
|
||||||
xmpp = ""
|
xmpp = "sch@pimux.de"
|
||||||
mix = ""
|
mix = ""
|
||||||
muc = ""
|
muc = "syndication@conference.movim.eu"
|
||||||
irc_channel = "#blasta"
|
irc_channel = "#blasta"
|
||||||
irc_server = ""
|
irc_server = ""
|
||||||
|
|
||||||
|
|
|
@ -115,15 +115,15 @@ h3, h4, h5 {
|
||||||
padding: 0 0.4em;
|
padding: 0 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title:first-child {
|
#posts > dd:first-child {
|
||||||
margin-block-start: 2.22em;
|
margin-block-start: 2.22em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
#posts > dd {
|
||||||
margin-block-start: 1.33em;
|
margin-block-start: 1.33em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > h4 {
|
article > h4 {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -11,8 +11,7 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
|
|
||||||
<xsl:output
|
<xsl:output
|
||||||
method = 'html'
|
method = 'html'
|
||||||
indent = 'yes'
|
indent = 'yes' />
|
||||||
omit-xml-decleration='no' />
|
|
||||||
|
|
||||||
<!-- set page metadata -->
|
<!-- set page metadata -->
|
||||||
<xsl:template name='metadata'>
|
<xsl:template name='metadata'>
|
||||||
|
@ -67,7 +66,7 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
<!-- feed title -->
|
<!-- feed title -->
|
||||||
<h1>
|
<h1>
|
||||||
<img src='/graphic/blasta_syndicate.svg'/>
|
<img src='/graphic/blasta_syndicate.svg'/>
|
||||||
 
|
 
|
||||||
<xsl:value-of select='atom:title'/>
|
<xsl:value-of select='atom:title'/>
|
||||||
</h1>
|
</h1>
|
||||||
<dl id='navigation'>
|
<dl id='navigation'>
|
||||||
|
@ -77,8 +76,18 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
<dd>
|
<dd>
|
||||||
<xsl:element name='a'>
|
<xsl:element name='a'>
|
||||||
<xsl:attribute name='href'>
|
<xsl:attribute name='href'>
|
||||||
<xsl:value-of select='atom:link'/>
|
<xsl:value-of select='atom:link[@rel="alternate" and @type="text/html"]/@href'/>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
|
<xsl:attribute name='title'>Return to Blasta.</xsl:attribute>
|
||||||
|
Return
|
||||||
|
</xsl:element>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<xsl:element name='a'>
|
||||||
|
<xsl:attribute name='href'>
|
||||||
|
<xsl:value-of select='atom:link[@rel="self"]/@href'/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:attribute name='download'>blasta_atom_syndication_feed.atom</xsl:attribute>
|
||||||
<xsl:attribute name='id'>follow</xsl:attribute>
|
<xsl:attribute name='id'>follow</xsl:attribute>
|
||||||
<xsl:attribute name='title'>Subscribe to updates with a news reader software.</xsl:attribute>
|
<xsl:attribute name='title'>Subscribe to updates with a news reader software.</xsl:attribute>
|
||||||
Follow
|
Follow
|
||||||
|
@ -102,6 +111,16 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
SubToMe
|
SubToMe
|
||||||
</a>
|
</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<xsl:element name='a'>
|
||||||
|
<xsl:attribute name='href'>
|
||||||
|
<xsl:value-of select='atom:link[@rel="alternate" and @type="x-scheme-handler/xmpp"]/@href'/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:attribute name='id'>subscribe</xsl:attribute>
|
||||||
|
<xsl:attribute name='title'>Subscribe to updates with an XMPP software.</xsl:attribute>
|
||||||
|
Subscribe
|
||||||
|
</xsl:element>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href='/help/about/xmpp'
|
<a href='/help/about/xmpp'
|
||||||
title='Of the benefits of XMPP.'>
|
title='Of the benefits of XMPP.'>
|
||||||
|
@ -127,7 +146,7 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
<div>
|
<div>
|
||||||
<h3>
|
<h3>
|
||||||
<img src='/graphic/syndicate.svg' height='22' width='22'/>
|
<img src='/graphic/syndicate.svg' height='22' width='22'/>
|
||||||
 
|
 
|
||||||
<xsl:value-of select='atom:subtitle'/>
|
<xsl:value-of select='atom:subtitle'/>
|
||||||
</h3>
|
</h3>
|
||||||
<!-- xsl:for-each select='atom:entry[position() <21]' -->
|
<!-- xsl:for-each select='atom:entry[position() <21]' -->
|
||||||
|
@ -164,21 +183,20 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
<h5 class='related'>
|
<h5 class='related'>
|
||||||
 
|
|
||||||
<img alt='💡'
|
<img alt='💡'
|
||||||
height='16'
|
height='16'
|
||||||
src='/graphic/xmpp.svg'
|
src='/graphic/xmpp.svg'
|
||||||
width='16' />
|
width='16' />
|
||||||
 
|
 
|
||||||
<a href='/help/about/xmpp/pubsub'>XMPP</a>
|
<a href='/help/about/xmpp/pubsub'>/help/about/xmpp/pubsub</a>
|
||||||
 
|
 
|
||||||
<img alt='⚛'
|
<img alt='⚛'
|
||||||
class='enlarge'
|
class='enlarge'
|
||||||
height='16'
|
height='16'
|
||||||
src='/graphic/syndicate.svg'
|
src='/graphic/syndicate.svg'
|
||||||
width='16' />
|
width='16' />
|
||||||
 
|
 
|
||||||
<a href='/help/syndication'>Syndication</a>
|
<a href='/help/syndication'>/help/syndication</a>
|
||||||
</h5>
|
</h5>
|
||||||
<p>
|
<p>
|
||||||
<b>Congratulations!</b> You have reached to the final
|
<b>Congratulations!</b> You have reached to the final
|
||||||
|
@ -196,15 +214,15 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
the ones that would fit to you best!
|
the ones that would fit to you best!
|
||||||
</p>
|
</p>
|
||||||
<div class='details'>
|
<div class='details'>
|
||||||
<a href='?tags=filetype:atom'>filetype:atom </a>
|
<a href='?mode=feed&tags=filetype:atom'>filetype:atom </a>
|
||||||
<a href='?tags=filetype:rss'>filetype:rss </a>
|
<a href='?mode=feed&tags=filetype:rss'>filetype:rss </a>
|
||||||
<a href='?tags=filetype:xml'>filetype:xml </a>
|
<a href='?mode=feed&tags=filetype:xml'>filetype:xml </a>
|
||||||
<a href='?tags=software:akregator'>software:akregator </a>
|
<a href='?mode=feed&tags=software:akregator'>software:akregator </a>
|
||||||
<a href='?tags=software:fraidycat'>software:fraidycat </a>
|
<a href='?mode=feed&tags=software:fraidycat'>software:fraidycat </a>
|
||||||
<a href='?tags=software:liferea'>software:liferea </a>
|
<a href='?mode=feed&tags=software:liferea'>software:liferea </a>
|
||||||
<a href='?tags=software:otter-browser'>software:otter-browser </a>
|
<a href='?mode=feed&tags=software:otter-browser'>software:otter-browser </a>
|
||||||
<a href='?tags=software:raven-reader'>software:raven-reader </a>
|
<a href='?mode=feed&tags=software:raven-reader'>software:raven-reader </a>
|
||||||
<a href='?tags=niche:syndication'>niche:syndication</a>
|
<a href='?mode=feed&tags=niche:syndication'>niche:syndication</a>
|
||||||
<h5 class='updated'>2024-08-22T17:09:04+03:00</h5>
|
<h5 class='updated'>2024-08-22T17:09:04+03:00</h5>
|
||||||
<h5 class='author'>
|
<h5 class='author'>
|
||||||
<a href='/jid/sch@pimux.de'>sch@pimux.de</a>
|
<a href='/jid/sch@pimux.de'>sch@pimux.de</a>
|
||||||
|
@ -252,13 +270,13 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
PubSub
|
PubSub
|
||||||
</xsl:element>
|
</xsl:element>
|
||||||
​ 
|
 
|
||||||
💬
|
💬
|
||||||
<xsl:element name='a'>
|
<xsl:element name='a'>
|
||||||
<xsl:attribute name='href'>
|
<xsl:attribute name='href'>
|
||||||
<xsl:value-of select='atom:link[@rel="related" and @type="text/html"]/@href'/>
|
<xsl:value-of select='atom:link[@rel="related" and @type="text/html"]/@href'/>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
People
|
Folksonomy
|
||||||
</xsl:element>
|
</xsl:element>
|
||||||
</h5>
|
</h5>
|
||||||
<!-- entry content -->
|
<!-- entry content -->
|
||||||
|
@ -271,11 +289,11 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
<xsl:for-each select='atom:category'>
|
<xsl:for-each select='atom:category'>
|
||||||
<xsl:element name='a'>
|
<xsl:element name='a'>
|
||||||
<xsl:attribute name='href'>
|
<xsl:attribute name='href'>
|
||||||
?tags=<xsl:value-of select='@term'/>
|
?mode=feed&tags=<xsl:value-of select='@term'/>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
<xsl:value-of select='@term'/>
|
<xsl:value-of select='@term'/>
|
||||||
</xsl:element>
|
</xsl:element>
|
||||||
 
|
 
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
<h5 class='date'>
|
<h5 class='date'>
|
||||||
<!-- entry date -->
|
<!-- entry date -->
|
||||||
|
@ -362,21 +380,20 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
<h5 class='related'>
|
<h5 class='related'>
|
||||||
 
|
|
||||||
<img alt='💡'
|
<img alt='💡'
|
||||||
height='16'
|
height='16'
|
||||||
src='/graphic/xmpp.svg'
|
src='/graphic/xmpp.svg'
|
||||||
width='16' />
|
width='16' />
|
||||||
 
|
 
|
||||||
<a href='/help/about/xmpp/pubsub'>XMPP</a>
|
<a href='/help/about/xmpp/pubsub'>About XMPP</a>
|
||||||
 
|
 
|
||||||
<img alt='⚛'
|
<img alt='⚛'
|
||||||
class='enlarge'
|
class='enlarge'
|
||||||
height='16'
|
height='16'
|
||||||
src='/graphic/syndicate.svg'
|
src='/graphic/syndicate.svg'
|
||||||
width='16' />
|
width='16' />
|
||||||
 
|
 
|
||||||
<a href='/help/syndication'>Syndication</a>
|
<a href='/help/syndication'>About Syndication</a>
|
||||||
</h5>
|
</h5>
|
||||||
<p>
|
<p>
|
||||||
This is a concise introduction to the syndication
|
This is a concise introduction to the syndication
|
||||||
|
@ -407,17 +424,17 @@ xmlns:atom='http://www.w3.org/2005/Atom'>
|
||||||
Language Family (XSL).
|
Language Family (XSL).
|
||||||
</p>
|
</p>
|
||||||
<div class='details'>
|
<div class='details'>
|
||||||
<a href='?tags=brand:atompub'>brand:atompub </a>
|
<a href='?mode=feed&tags=brand:atompub'>brand:atompub </a>
|
||||||
<a href='?tags=brand:atomsub'>brand:atomsub </a>
|
<a href='?mode=feed&tags=brand:atomsub'>brand:atomsub </a>
|
||||||
<a href='?tags=brand:pubsub'>brand:pubsub </a>
|
<a href='?mode=feed&tags=brand:pubsub'>brand:pubsub </a>
|
||||||
<a href='?tags=code:xslt'>code:xslt </a>
|
<a href='?mode=feed&tags=code:xslt'>code:xslt </a>
|
||||||
<a href='?tags=filetype:atom'>filetype:atom </a>
|
<a href='?mode=feed&tags=filetype:atom'>filetype:atom </a>
|
||||||
<a href='?tags=filetype:rss'>filetype:rss </a>
|
<a href='?mode=feed&tags=filetype:rss'>filetype:rss </a>
|
||||||
<a href='?tags=filetype:xml'>filetype:xml </a>
|
<a href='?mode=feed&tags=filetype:xml'>filetype:xml </a>
|
||||||
<a href='?tags=software:libervia'>software:libervia </a>
|
<a href='?mode=feed&tags=software:libervia'>software:libervia </a>
|
||||||
<a href='?tags=software:movim'>software:movim </a>
|
<a href='?mode=feed&tags=software:movim'>software:movim </a>
|
||||||
<a href='?tags=software:reeder'>software:reeder </a>
|
<a href='?mode=feed&tags=software:reeder'>software:reeder </a>
|
||||||
<a href='?tags=niche:syndication'>niche:syndication</a>
|
<a href='?mode=feed&tags=niche:syndication'>niche:syndication</a>
|
||||||
<h5 class='updated'>2024-08-22T17:09:04+03:00</h5>
|
<h5 class='updated'>2024-08-22T17:09:04+03:00</h5>
|
||||||
<h5 class='author'>
|
<h5 class='author'>
|
||||||
<a href='/jid/sch@pimux.de'>sch@pimux.de</a>
|
<a href='/jid/sch@pimux.de'>sch@pimux.de</a>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -104,9 +107,10 @@
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
With the collaborative indexing system which Blasta offers,
|
With the collaborative indexing system which Blasta offers,
|
||||||
you can be rest assured that you will find the references
|
and its <a href="/help/about/folksonomy">folksonomical</a>
|
||||||
and resources that you need in order to be productive and
|
nature you can be rest assured that you will find the
|
||||||
get that you need.
|
references and resources that you need in order to be
|
||||||
|
productive and get that you need.
|
||||||
</p>
|
</p>
|
||||||
<h4>The things that you can do with Blasta are endless</h4>
|
<h4>The things that you can do with Blasta are endless</h4>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<link href="{{request.url}}"
|
<link href="{{request.url}}"
|
||||||
rel="self"
|
rel="self"
|
||||||
type="text/html" />
|
type="text/html" />
|
||||||
<link href="{{request.url.__str__().replace('?mode=feed', '')}}"
|
<link href="{{request.url.__str__().replace('mode=feed&', '', 1)}}"
|
||||||
rel="alternate"
|
rel="alternate"
|
||||||
type="text/html" />
|
type="text/html" />
|
||||||
<link href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}"
|
<link href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}"
|
||||||
|
|
|
@ -30,23 +30,46 @@
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/save">Add</a>
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/private">Private</a>
|
{% if node_type == 'public' %}
|
||||||
|
<b>Public</b>
|
||||||
|
{% else %}
|
||||||
|
<a href="/jid">Public</a>
|
||||||
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/read">Read</a>
|
{% if node_type == 'private' %}
|
||||||
|
<b>Private</b>
|
||||||
|
{% else %}
|
||||||
|
<a href="/private">Private</a>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
{% if node_type == 'read' %}
|
||||||
|
<b>Read</b>
|
||||||
|
{% else %}
|
||||||
|
<a href="/read">Read</a>
|
||||||
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/search{% if jid %}/jid/{{jid}}{% endif %}">Search</a>
|
<a href="/search{% if jid %}/jid/{{jid}}{% endif %}">Search</a>
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/popular">Popular</a>
|
{% if page_type == 'popular' %}
|
||||||
|
<b>Popular</b>
|
||||||
|
{% else %}
|
||||||
|
<a href="/popular">Popular</a>
|
||||||
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/recent">Recent</a>
|
{% if page_type == 'recent' %}
|
||||||
|
<b>Recent</b>
|
||||||
|
{% else %}
|
||||||
|
<a href="/recent">Recent</a>
|
||||||
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
@ -97,13 +120,13 @@
|
||||||
your PubSub bookmarks directory with Blasta!
|
your PubSub bookmarks directory with Blasta!
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<dl id="posts">
|
{% if entries %}
|
||||||
{% if entries %}
|
<dl id="posts">
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<dd>
|
<dd>
|
||||||
<article class="h-entry title">
|
<article class="h-entry">
|
||||||
<h4>
|
<h4>
|
||||||
<a class="p-name"
|
<a class="p-name title"
|
||||||
href="{{entry['link']}}">
|
href="{{entry['link']}}">
|
||||||
{{entry['title']}}</a>
|
{{entry['title']}}</a>
|
||||||
</h4>
|
</h4>
|
||||||
|
@ -123,7 +146,7 @@
|
||||||
delete</a>
|
delete</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/url/{{entry['url_hash']}}/edit">
|
<a href="/url/{{entry['url_hash']}}/edit">
|
||||||
add</a>
|
add this</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class="p-summary summary">{{entry['summary']}}</p>
|
<p class="p-summary summary">{{entry['summary']}}</p>
|
||||||
|
@ -135,7 +158,6 @@
|
||||||
href="{% if jid %}/jid/{{jid}}{% elif path in ('query', 'url') %}/{% endif %}?tags={{tag}}">
|
href="{% if jid %}/jid/{{jid}}{% elif path in ('query', 'url') %}/{% endif %}?tags={{tag}}">
|
||||||
{{tag}}
|
{{tag}}
|
||||||
</a>
|
</a>
|
||||||
​ 
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
by
|
by
|
||||||
|
@ -167,7 +189,6 @@
|
||||||
<span>details</span>
|
<span>details</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
​ 
|
|
||||||
at
|
at
|
||||||
<span class="dt-published date"
|
<span class="dt-published date"
|
||||||
datetime="{{entry['published']}}">
|
datetime="{{entry['published']}}">
|
||||||
|
@ -177,18 +198,23 @@
|
||||||
</article>
|
</article>
|
||||||
</dd>
|
</dd>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
</dl>
|
||||||
</dl>
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div id="related-tags">
|
<div id="related-tags">
|
||||||
<h3>Related tags</h3>
|
<h3>
|
||||||
|
{% if path == 'url' %}
|
||||||
|
Tags
|
||||||
|
{% else %}
|
||||||
|
Related tags
|
||||||
|
{% endif %}
|
||||||
|
</h3>
|
||||||
<dl>
|
<dl>
|
||||||
{% for tag in tags %}
|
{% for tag in tags %}
|
||||||
<dd>
|
<dd>
|
||||||
<a href="{% if jid %}/jid/{{jid}}{% elif path in ('query', 'url') %}/{% endif %}?tags={{tag}}">
|
<a href="{% if jid %}/jid/{{jid}}{% elif path in ('query', 'url') %}/{% endif %}?tags={{tag}}">
|
||||||
{{tag}}
|
{{tag}}
|
||||||
</a>
|
</a>
|
||||||
​ 
|
|
||||||
{% if tags[tag] %}
|
{% if tags[tag] %}
|
||||||
({{tags[tag]}})
|
({{tags[tag]}})
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -224,14 +250,12 @@
|
||||||
<a href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}">
|
<a href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}">
|
||||||
PubSub
|
PubSub
|
||||||
</a>
|
</a>
|
||||||
​ 
|
|
||||||
and
|
and
|
||||||
<img alt="⚛" class="enlarge" src="/graphic/syndicate.svg" width="16" height="16"/>
|
<img alt="⚛" class="enlarge" src="/graphic/syndicate.svg" width="16" height="16"/>
|
||||||
<a href="/{% if jid %}jid/{% endif %}{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}">
|
<a href="/{% if jid %}jid/{% endif %}{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}">
|
||||||
RSS
|
RSS
|
||||||
<!-- img src="/graphic/atom.svg" width="36" height="14" alt="Atom"/ -->
|
<!-- img src="/graphic/atom.svg" width="36" height="14" alt="Atom"/ -->
|
||||||
</a>
|
</a>
|
||||||
​ 
|
|
||||||
syndication feeds for this page are available.
|
syndication feeds for this page are available.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<a href="/recent">Recent</a>
|
<a href="/recent">Recent</a>
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/connect">Connect</a>
|
<b>Connect</b>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<b>Add</b>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -201,6 +204,17 @@ to view details.">
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td>
|
<td>
|
||||||
|
{% if message %}
|
||||||
|
<p>
|
||||||
|
<i>
|
||||||
|
{{message}}
|
||||||
|
{% if message_link %}
|
||||||
|
<a href="{{message_link['href']}}">
|
||||||
|
{{message_link['text']}}</a>.
|
||||||
|
{% endif %}
|
||||||
|
</i>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
<p>
|
<p>
|
||||||
<i>
|
<i>
|
||||||
Fields that are marked with an asterisk
|
Fields that are marked with an asterisk
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
209
template/folksonomy.xhtml
Normal file
209
template/folksonomy.xhtml
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="color-scheme" content="dark light" />
|
||||||
|
<title>Blasta / questions</title>
|
||||||
|
<link rel="shortcut icon" href="/graphic/blasta.svg"/>
|
||||||
|
<link rel='icon' type='image/svg+xml' href='/graphic/blasta.svg'/>
|
||||||
|
<link rel='stylesheet' type='text/css' media='screen' href='/stylesheet/stylesheet.css'/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<div id="header" class="row">
|
||||||
|
<h1>
|
||||||
|
<img src="/graphic/blasta.svg"/>
|
||||||
|
<a href="/">Blasta</a> / <a href="/help">help</a> / <a href="/help/about">about</a> / folksonomy
|
||||||
|
</h1>
|
||||||
|
<dl id="navigation">
|
||||||
|
<dd>
|
||||||
|
<img src="/graphic/blasta.svg"/>
|
||||||
|
</dd>
|
||||||
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/jid">Public</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/private">Private</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/read">Read</a>
|
||||||
|
</dd>
|
||||||
|
{% endif %}
|
||||||
|
<dd>
|
||||||
|
<a href="/search{% if jabber_id %}/jid/{{jabber_id}}{% endif %}">Search</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/popular">Popular</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/recent">Recent</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
{% if jabber_id %}
|
||||||
|
<a href="/disconnect">Disconnect</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/connect">Connect</a>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div id="main" class="row">
|
||||||
|
<div id="content">
|
||||||
|
<h2> PubSub Bookmarks</h2>
|
||||||
|
<p>
|
||||||
|
» A practice for people to organize and share information in
|
||||||
|
a collaborative and decentralized manner.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
Folksonomy
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Folksonomy is a system of classification that is created by
|
||||||
|
individual people, rather than by professionals (who
|
||||||
|
sometimes refer themselves as experts) such as archivers or
|
||||||
|
librarians. It is a fashion for people to collaboratively
|
||||||
|
tag and categorize information, often using keywords or
|
||||||
|
labels.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Characteristics
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Among the characteristics of folksonomy are: independency,
|
||||||
|
collaborativeness, and being dynamic;
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Tags are self-generated by individual people, not by a
|
||||||
|
centralized authority;
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Tags can be added by multiple people to the same item,
|
||||||
|
and thereby they create a collective understanding;
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Tags can be added, removed, and updated over time,
|
||||||
|
reflecting evolving usage, accuracy and interests;
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
There is no single source of truth or control over the
|
||||||
|
tagging process.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Benefits
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Because people can easily find relevant content by searching
|
||||||
|
for specific tags; and shared tagging promotes collective
|
||||||
|
understanding and knowledge creation; and people feel more
|
||||||
|
involved and empowered by contributing their own insights.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The benefits of folksonomies spans from improved
|
||||||
|
discoverability of contents to enhanced collaboration and
|
||||||
|
increased engagement of people by contributing and
|
||||||
|
benefiting to the overhaul system.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
It was written in Adam Mathes' recent paper on folksonomies that:
|
||||||
|
</p>
|
||||||
|
<p class="quote">
|
||||||
|
“There is a fundamental difference in the activities of
|
||||||
|
browsing to find interesting content, as opposed to direct
|
||||||
|
searching to find relevant documents in a query. It is
|
||||||
|
similar to the difference between exploring a problem space
|
||||||
|
to formulate questions, as opposed to actually looking for
|
||||||
|
answers to specifically formulated questions. Information
|
||||||
|
seeking behavior varies based on context.”
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Conclusion
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
By practicing and engaging in folksonomy systems, people
|
||||||
|
find many interesting resources that are related to their
|
||||||
|
special and specific needs, that they could not have found
|
||||||
|
using search engines. Blasta has some interesting advantages
|
||||||
|
over search engines, and one of them is being folksonomy
|
||||||
|
driven.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The power of the people cannot be more evident than the
|
||||||
|
awesome resource that is Wikipedia, albeit is has been
|
||||||
|
gradually controlled by
|
||||||
|
<a href="https://www.fivefilters.org/2023/glenn-greenwald-on-wikipedia-bias/">
|
||||||
|
special interests</a>. Imagine what might happen if a search
|
||||||
|
engine (e.g. YaCy) can be engineered by people!
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Resources
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="http://adammathes.com/academic/computer-mediated-communication/folksonomies.html">
|
||||||
|
Folksonomies - Cooperative Classification and Communication Through Shared Metadata
|
||||||
|
</a>
|
||||||
|
​ 
|
||||||
|
(adammathes.com)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://www.sylloge.com/personal/2004/08/folksonomy-social-classification-great.html">
|
||||||
|
Folksonomy : social classification
|
||||||
|
</a>
|
||||||
|
​ 
|
||||||
|
(sylloge.com)
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<br/>
|
||||||
|
<p class="quote bottom">
|
||||||
|
“I think the lack of hierarchy, synonym control and semantic
|
||||||
|
precision are precisely why it works. Free typing loose
|
||||||
|
associations is just a lot easier than making a decision
|
||||||
|
about the degree of match to a pre-defined category
|
||||||
|
(especially hierarchical ones).”
|
||||||
|
― Stewart Butterfield
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="footer" class="row">
|
||||||
|
<dl>
|
||||||
|
<dd>
|
||||||
|
<img src="/graphic/blasta.svg" alt="logo"/>
|
||||||
|
<a href="/">blasta</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/about">about</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/about/xmpp">xmpp</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/about/xmpp/pubsub">pubsub</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="{{journal}}">journal</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help">help</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/policy">policy</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/feeds">rss</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/contact">contact</a>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -64,6 +67,7 @@
|
||||||
<div>
|
<div>
|
||||||
<h4>About</h4>
|
<h4>About</h4>
|
||||||
<p><a href="/help/about">Blasta</a></p>
|
<p><a href="/help/about">Blasta</a></p>
|
||||||
|
<p><a href="/help/about/folksonomy">Folksonomy</a></p>
|
||||||
<p><a href="/help/about/ideas">Ideas</a></p>
|
<p><a href="/help/about/ideas">Ideas</a></p>
|
||||||
<p><a href="/help/about/philosophy">Philosophy</a></p>
|
<p><a href="/help/about/philosophy">Philosophy</a></p>
|
||||||
<p><a href="/help/about/projects">Projects</a></p>
|
<p><a href="/help/about/projects">Projects</a></p>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
256
template/people.xhtml
Normal file
256
template/people.xhtml
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="color-scheme" content="dark light" />
|
||||||
|
<title>Blasta / {{path}}</title>
|
||||||
|
<link rel="shortcut icon" href="/graphic/blasta.svg" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/graphic/blasta.svg" />
|
||||||
|
<link rel="stylesheet" type="text/css" media="screen"
|
||||||
|
href="/stylesheet/stylesheet.css" />
|
||||||
|
<link rel="alternate" type="application/atom+xml"
|
||||||
|
title="Follow updates on /{% if jid %}jid/{% endif %}{{syndicate}}{% if param_tags %} for Tag: #{{param_tags}}{% endif %}{% if param_url %} for URL: {{param_url}}{% endif %}{% if param_hash %} for hash: {{param_hash}}{% endif %}"
|
||||||
|
href="/{% if jid %}jid/{% endif %}{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}" />
|
||||||
|
<link rel="alternate" type="application/atom+xml"
|
||||||
|
title="Subscribe to PubSub /{{syndicate}}{% if param_tags %} for Tag: #{{param_tags}}{% endif %}{% if param_url %} for URL: {{param_url}}{% endif %}{% if param_hash %} for hash: {{param_hash}}{% endif %}"
|
||||||
|
href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<div id="header" class="row">
|
||||||
|
<h1>
|
||||||
|
<img src="/graphic/blasta.svg"/>
|
||||||
|
<a href="/">Blasta</a> / {{path}}
|
||||||
|
</h1>
|
||||||
|
<dl id="navigation">
|
||||||
|
<dd>
|
||||||
|
<img src="/graphic/blasta.svg"/>
|
||||||
|
</dd>
|
||||||
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/jid">Public</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/private">Private</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/read">Read</a>
|
||||||
|
</dd>
|
||||||
|
{% endif %}
|
||||||
|
<dd>
|
||||||
|
<a href="/search{% if jid %}/jid/{{jid}}{% endif %}">Search</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/popular">Popular</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/recent">Recent</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
{% if jabber_id %}
|
||||||
|
<a href="/disconnect">Disconnect</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/connect">Connect</a>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div id="main" class="row">
|
||||||
|
<div id="content">
|
||||||
|
<h2> PubSub Bookmarks</h2>
|
||||||
|
{% if pager %}
|
||||||
|
{% if page_next or page_prev %}
|
||||||
|
<div id="navigate-top">
|
||||||
|
{% if page_prev %}
|
||||||
|
«
|
||||||
|
<a href="?page={{page_prev}}{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_query %}&q={{param_query}}{% endif %}">
|
||||||
|
<b>retract</b></a>
|
||||||
|
{% else %}
|
||||||
|
<span class="inactive">« retract</span>
|
||||||
|
{% endif %}
|
||||||
|
or
|
||||||
|
{% if page_next %}
|
||||||
|
<a href="?page={{page_next}}{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_query %}&q={{param_query}}{% endif %}">
|
||||||
|
<b>proceed</b></a>
|
||||||
|
»
|
||||||
|
{% else %}
|
||||||
|
<span class="inactive">proceed »</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<p>» {{message}}</p>
|
||||||
|
<h3>{{description}}</h3>
|
||||||
|
{% if entries %}
|
||||||
|
<dl id="posts">
|
||||||
|
{% for entry in entries %}
|
||||||
|
<dd>
|
||||||
|
<article>
|
||||||
|
<h4>
|
||||||
|
<a class="title"
|
||||||
|
href="{{entry['link']}}">
|
||||||
|
{{entry['title']}}</a>
|
||||||
|
</h4>
|
||||||
|
<!-- TODO Edit to be possible if entry is present -->
|
||||||
|
<!-- {% if jabber_id and entry['present'] %}{% endif %} -->
|
||||||
|
{% if jabber_id %}
|
||||||
|
{% if restore %}
|
||||||
|
<a href="{{link_save}}">restore</a>
|
||||||
|
{% elif delete %}
|
||||||
|
<a href="/url/{{entry['url_hash']}}/delete"
|
||||||
|
id="confirm">confirm deletion</a>
|
||||||
|
{% elif jabber_id == jid or exist or path in ('private', 'read') %}
|
||||||
|
<a href="/url/{{entry['url_hash']}}/edit">
|
||||||
|
edit</a>
|
||||||
|
/
|
||||||
|
<a href="/url/{{entry['url_hash']}}/confirm">
|
||||||
|
delete</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/url/{{entry['url_hash']}}/edit">
|
||||||
|
add</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<p class="summary">{{entry['summary']}}</p>
|
||||||
|
<div class="details">
|
||||||
|
{% if entry['tags'] | length > 0 %}
|
||||||
|
to
|
||||||
|
{% for tag in entry['tags'] %}
|
||||||
|
<a href="{% if jid %}/jid/{{jid}}{% elif path in ('query', 'url') %}/{% endif %}?tags={{tag}}">
|
||||||
|
{{tag}}
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
at
|
||||||
|
<span>
|
||||||
|
{{entry['published_mod']}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</dd>
|
||||||
|
{% endfor %}
|
||||||
|
</dl>
|
||||||
|
{% endif %}
|
||||||
|
<br/>
|
||||||
|
<hr/>
|
||||||
|
{% if people %}
|
||||||
|
<h4>
|
||||||
|
This resource is shared amongst {{entries[0]['instances']}} people
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
<dl id="people">
|
||||||
|
{% for jid in people %}
|
||||||
|
<dt class="h-entry">
|
||||||
|
<dt>
|
||||||
|
<h5>
|
||||||
|
by <a class="p-author" href="/jid/{{jid}}">{{jid}}</a>
|
||||||
|
</h5>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
to
|
||||||
|
{% if people[jid] | length > 0 %}
|
||||||
|
{% for tag in people[jid] %}
|
||||||
|
<a class="p-category"
|
||||||
|
href="{% if jid %}/jid/{{jid}}{% elif path in ('query', 'url') %}/{% endif %}?tags={{tag}}">
|
||||||
|
{{tag}}
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
</dt>
|
||||||
|
{% endfor %}
|
||||||
|
</dl>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div id="related-tags">
|
||||||
|
<h3>Your tags</h3>
|
||||||
|
<dl>
|
||||||
|
{% for tag in tags %}
|
||||||
|
<dd>
|
||||||
|
<a href="{% if jid %}/jid/{{jid}}{% elif path in ('query', 'url') %}/{% endif %}?tags={{tag}}">
|
||||||
|
{{tag}}
|
||||||
|
</a>
|
||||||
|
{% if tags[tag] %}
|
||||||
|
({{tags[tag]}})
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
{% endfor %}
|
||||||
|
<dd>
|
||||||
|
»
|
||||||
|
<a href="/tag/{% if jid %}{{jid}}{% endif %}">see more tags</a>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if pager %}
|
||||||
|
{% if page_next or page_prev %}
|
||||||
|
<div id="navigate-bottom" class="row">
|
||||||
|
{% if page_prev %}
|
||||||
|
« <a href="?page={{page_prev}}{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_query %}&q={{param_query}}{% endif %}"><b>retract</b></a>
|
||||||
|
{% else %}
|
||||||
|
<span class="inactive">« retract</span>
|
||||||
|
{% endif %}
|
||||||
|
or
|
||||||
|
{% if page_next %}
|
||||||
|
<a href="?page={{page_next}}{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_query %}&q={{param_query}}{% endif %}"><b>proceed</b></a> »
|
||||||
|
{% else %}
|
||||||
|
<span class="inactive">proceed »</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<div id="subscribe" class="row">
|
||||||
|
<p>
|
||||||
|
<img alt="💡" src="/graphic/xmpp.svg" width="16" height="16"/>
|
||||||
|
<a href="xmpp:{{pubsub_jid}}?pubsub;action=subscribe;node={{node_id}}">
|
||||||
|
PubSub
|
||||||
|
</a>
|
||||||
|
and
|
||||||
|
<img alt="⚛" class="enlarge" src="/graphic/syndicate.svg" width="16" height="16"/>
|
||||||
|
<a href="/{% if jid %}jid/{% endif %}{{syndicate}}?mode=feed{% if param_tags %}&tags={{param_tags}}{% endif %}{% if param_url %}&url={{param_url}}{% endif %}{% if param_hash %}&hash={{param_hash}}{% endif %}">
|
||||||
|
RSS
|
||||||
|
<!-- img src="/graphic/atom.svg" width="36" height="14" alt="Atom"/ -->
|
||||||
|
</a>
|
||||||
|
syndication feeds for this page are available.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="footer" class="row">
|
||||||
|
<dl>
|
||||||
|
<dd>
|
||||||
|
<img src="/graphic/blasta.svg" alt="logo"/>
|
||||||
|
<a href="/">blasta</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/about">about</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/about/xmpp">xmpp</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/about/xmpp/pubsub">pubsub</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="{{journal}}">journal</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help">help</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/policy">policy</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/help/feeds">rss</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a href="/contact">contact</a>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -79,7 +82,9 @@
|
||||||
<p>
|
<p>
|
||||||
The method instance:keyword is a practice which improves
|
The method instance:keyword is a practice which improves
|
||||||
bookmarks organizing, archiving, filtering and searching, as
|
bookmarks organizing, archiving, filtering and searching, as
|
||||||
it narrows the context of a given bookmark.
|
it narrows the context of a given bookmark, and therefore
|
||||||
|
improves <a href="/help/about/folksonomy">Folksonomy</a>
|
||||||
|
practices.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Suppose you have two bookmarks; one is related to
|
Suppose you have two bookmarks; one is related to
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -33,7 +36,7 @@
|
||||||
</dd>
|
</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/search{% if jid %}/jid/{{jid}}{% endif %}">Search</a>
|
<b>Search</b>
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/popular">Popular</a>
|
<a href="/popular">Popular</a>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<img src="/graphic/blasta.svg"/>
|
<img src="/graphic/blasta.svg"/>
|
||||||
</dd>
|
</dd>
|
||||||
{% if jabber_id %}
|
{% if jabber_id %}
|
||||||
|
<dd>
|
||||||
|
<a href="/save">Add</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jid">Public</a>
|
<a href="/jid">Public</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
Loading…
Reference in a new issue