The drupal.org redesign is anticipating using Flag for bookmarking of pages on drupal.org. Similar to this module, we want to be able to bookmark any page, not just ones that are nodes. This module looks exactly like what we want, except that I'm worried about the creation of URLs in the database for every page on the entire site. I developed a similar module (called flag_urls) that is nearly identical to flag_page with the following differences:
- It creates its own Flag link type and menu callbacks for flagging.
- This menu callback makes entries in the database the first time a page is flagged.
- It's not as developed (no Views support, no hook_block).
Unfortunately making our own link type significantly increases the size of the module, plus I'm not sure how well it will work with anonymous flagging in the 2.x version of Flag. Would you be interested in collaborating on these goals so that we could use flag_page for drupal.org?
I've attached my in-progress module, of course I'll convert this to patches to flag_page if you're interested in collaborating. Thanks!
| Comment | File | Size | Author |
|---|---|---|---|
| #16 | 896814_flag_page_hash_keys_and_lazy_loading_4.patch | 22.94 KB | alexpott |
| #6 | 896814_flag_page_hash_keys_and_lazy_loading_3.patch | 22.54 KB | alexpott |
| #5 | 896814_flag_page_hash_keys_and_lazy_loading_2.patch | 8.24 KB | alexpott |
| #4 | 896814_flag_page_hash_keys_and_lazy_loading.patch | 5.89 KB | alexpott |
| flag_urls.zip | 6.41 KB | quicksketch |
Comments
Comment #1
alexpottI'm more than interested in collaborating!!!! (Nearly fell off the proverbial chair reading your message)
Patches welcome and if you want to be a co-maintainer I'd have no issue with that either (how could I - the flag module's your work ;) )
Perhaps we'll chat on IRC and sort out what needs to be done to get flag_page to a state where drupal.org can use it?!?
Comment #2
quicksketchFantastic! I'll work on rolling this as a patch to your module. Just a warning: I'm fairly sure the changes are going to be fairly substantial, since flagging a non-existent item is quite an unusual challenge. We'll probably need to modify your flag_page.inc class a bit.
There's also a mostly superfluous change adding a "hash" column to the flag_page_data table, this is a sha1 hash of the URL (which I let go up to 1024 characters) which is for performance, since we can lookup a sha1 hash on a 40-character column much faster than a 1024 character varchar. This should help with the large number of URLs that we anticipate on drupal.org.
I'm super-excited to be working with another project maintainer on this, I'll post an update when I get a chance to merge my work into flag_page.
Comment #3
drummComment #4
alexpottHere's a patch that adds:
1. Adds and uses the hash column for performance
2. Lazy loads the flag_page_data table so only flagged pages and entered
3. It doesn't add any extra menu items - it uses a content id of -1 to indicate it's a new url
Comment #5
alexpottImproved the way titles are handled by passing in the page title on the url
Still to do - break up the flag_page_data into two tables (flag_page_data_url and flag_page_data_user) - so that if users can't override titles we don't create unnecessary rows in the flag_page_data and the overridden data will be stored in flag_page_data_user.
This should be mean that on d.o flag_page_data_url is kept to a minimum size - i.e. maximum row count would be number of urls on the site rather than urls * users
Comment #6
alexpottThis patch breaks flag_page_data into two tables flag_page_data_url and flag_page_data_user and makes the necessary changes to the views integration and contains all the improvements from #4 and #5.
Still to see what happens when anonymous flagging is enabled...
Comment #7
quicksketchI like this approach but I'm certain it's not going to work with anonymous flagging. Anonymous flags work by storing the content ID in a cookie. All the links are always shown in the unflagged state, then JavaScript goes through all the Content IDs in the cookie and replaces them with the flagged state. Since we're using a content ID of -1 for all unflagged content, anonymous users (in theory) would flag one item and then all content would appear flagged also.
Comment #8
alexpottI've not read much into anonymous flagging... but I enabled session_api... set the page_flag to allow anon's... and it appears to work... have a look... http://dev.vit-al.co.uk/flag_page
Comment #9
quicksketchDo you have page caching enabled? Flag only uses that behavior if it needs to deliver the same page to all anonymous users (since you can't put the link in a flagged state into the page cache).
Comment #10
alexpottJust enabled block level and normal caching mode... everything appears to work...
Tried it on aggressive and things fell apart.
Comment #11
alexpottOops... nope it's not working when caching is enabled... however... the error is not that it thinks everything page is flagged - it never seems to get the remove flag action - and once you've added one url it's the only url you can add...
Will see what I can do...
Comment #12
quicksketchYeah the "everything shows up as flagged" would probably only exist if you were using JavaScript toggles instead of the confirmation form, check your cookies to see how Flag keeps track of flagged content by ID. In any case the goal is to have the cookie content ID and the link content ID match, which is why I took the approach of my own link type with a sha1 of the URL as the ID, since it gave a unique ID that the JavaScript could use (though a numeric ID was still used in the database).
Comment #13
alexpottJust enabled the javascript toggle... and it's working... when page caching is enabled... but not when block caching is enabled... any ideas as to why? I think that the flag / unflag block can't be cached so I did this in flag_page_block:
Comment #14
alexpottCan you guarantee the uniqueness of the sha1 generated id?
Comment #15
alexpott'cache' => BLOCK_NO_CACHE does work - just need to delete the row from the block table to get it to rebuild...
Okay now http://dev.vit-al.co.uk/flag_page has page caching (normal - not aggressive) and block caching turned on. Everything appears to work apart from the javascript that replaces the flag action with the unflag action...
Comment #16
alexpottPatch with latest changes... anonymous users and block caching...
Known bugs - for anonymous users the flag link will disable and not be replaced by an unflag link.
Comment #17
quicksketchIt'd be pretty unusual to get a collision: http://en.wikipedia.org/wiki/Universally_unique_identifier
That's not specific to SHA1, but it's a similar probability. Given any site's individual URLs, I think it's safe to say you'll never get a conflict.
Comment #18
drummComment #19
drummAny progress on this? What can be done to help remove blockers?
Comment #20
alexpottI tracked the issue with anonymous flags to bug a in the flag module when you use an underscore in a flag name - I raised an issue and submitted a patch http://drupal.org/node/904144
As far as I know I've implemented all of quicksketch's ideas to make the module scale for d.o - I will do a dev release of 6.x-2.x branch when I get a sec.
Comment #21
alexpottI've released a new version of the module 6.x-2.0 which has all the improvements recommended by quicksketch.
Comment #22
rickvug commentedI've been doing some testing with flag_page and flag_note. In the 1.x series this combination works fine but in the 2.x series flag_note is note is not compatible with flag_page. I believe that this is due to this patch as flag is no longer referring to a pre-existing content id. This is reflected in the URL structure for flagging a node vs. flagging a page. The link for flag_page is not overridden to flagnote's menu item. Here are the examples:
flagnote/action/flag/bookmarks/5?destination=node%2F5&token=b5eca6c1b9af4c81e0c193c512a17d0f
flag/flag/bookmark_page/-1?destination=node%2F5&token=24db852edcd2f6b011cf999eef537ce3&title=Test
Any ideas? Time depending I may dig into this further myself. I've filed the bug at #999152: Flag note 2.x does not work with flag page 2.x.
Comment #23
rickvug commentedAs mentioned in #22 this patch introduced a compatibility problem between flag_note and flag_page. Removing the following code fixes the problem:
From what I can see everything still works fine with this change but I can't be sure about other issues. Anyone care to comment on a way forward with this regression?
I'm moving to "needs work since this issue is still open despite the patch being committed. Let me know if any bugs should be new issues from here on out.
Comment #24
alexpottI think the best way to get round this issue will be to make the lazy-loading optional (and advisable on large sites). And check for the existence of the flag_note module and warn users. I've created a new issue to track this work #1017484: Compatibility problem between flag_note and flag_page 6.2
Setting this issue to fixed as the lazy loading capability works as expected in flag page 6.x-2.0
Comment #25
Ravi.J commentedBy overriding get_link_type() and assingning flag_page as module for all link_types flag_page is overriding href and destination attributes used by other flag modules.
As a result modules such as flag_note don't work as they are suppose to be working.
Here is the hook_flag_link implementation of flag_note
and below is the hook_flag_link implementation by flag_page
If you look closely the difference between the two implementations is the callback URL "href". flag_note uses "flag/note/%/%/%" and flag_page uses "flag/%/%/%" . As a result once flag_page is activated control never reaches menu path "flag/note/".
I spent quite a it of time in trying to identify a way for passing additional attributes to hook_flag_links, however it doesn't seem to be possible without considerable changes to flag_preprocess_page().
function get_link_type() in flag_page.inc is resulting in other modules not working as they should, hence this function could be taken off till there is a better way.
Comment #26
Ravi.J commentedComment #27
rickvug commentedFixing status. This is done.