HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.


This discussion is related to the Snippets addon.
x00x00 MVP
edited April 2009 in Vanilla 1.0 Help

grep is your friend.


  • Uploaded version 0.1 of Snippets.
  • Uploaded version 0.1 of Snippets.

  • Snippets Help

    A Snippet works a bit like quote tags (such as in BBCode: [quote][cite]user[/cite]...[/quote]), which are used quote cite another comment in a discussion, except they are more precise, versatile and verifiable than quote tags. The Snippets parser will, where possible, render the Snippet in the format it was originally intended. You won't see the text quoted in the text input, which is because a Snippet is merely a reference to the text. However when you post it will render as if you have cut it out and plonked it in your comment (similarly if you are able to preview your comment before posting it).

    A Snippet looks like this::snip_user_title_123:You can put any text around it, so long as you do not touch anything between the two colons. Simply being of that form it will be detected, if it is a valid reference the content will be rendered in place from whence it came. Incidentally the Snippets parser is global, which means it doesn't matter what text format/filter you are using for your comment, the Snippet will be rendered as intended by the comment author. The 'user' part will be the user name of the comment you are Snippeting, the 'title' will be the title of the discussion, and the number at the end will be the comment number, which is used to look up the specific comment. A typical Snippet may render like so:
    Snippet of Comment 123 in Discussion 568 (title) by user userthe content of the comment Snippeted...
    Snippets Menu
    Snippets comes with a menu accessible through a 'Snippets' link, which is usually on the top right of each comment. As you have managed to find your way here you have probably already used it.
    Posting a Snippet
    If you want to use a Snippet of a comment is as simple as clicking on the 'post Snippet' in the Snippet menu
    Snippet Store
    The Snippet Store gives you a bit more flexibility than piecemeal quoting. It is your own personal Snippet repository. If you save a Snippet to your Snippet Store it will stay there until you remove it, clear the store, or your session ends (typically due to logging out). When you go to post a comment or start a discussion all your saved Snippets will be available. You can move between different discussions storing Snippets with ease, regardless of which discussion you wish to add them too. You can select the Snippet simply by clicking on the one in the store list box. To select multiples try holding down the Ctrl key and then clicking on each Snippet you want. Once you select the ones you want, click 'Add to Post' button. If there are no Snippets stored, the store will not be displayed. You are able to remove Snippets and clear the store from the Snippet menu of a comment or by using the buttons under the Snippets (selecting the Snippets first in the case of removal)
    Nested Snippets
    Snippets may be nested, in other words a Snippet of a comment with a Snippet in it, etc. All Snippets will render as intended (where possible) regardless of nesting level.
    Fragment Snippets
    You do not have to Snippet a whole comment all the time. You can Snippet any part of a comment like a 'cutting'. The easiest way to do this is to select the text in the comment by clicking and dragging over the text/paragraph until it is highlighted (being careful to be within the body of the comment and not over the comment header or it will not work). Once you have done so you have various shortcuts you can use. If you hold down the 'Alt' key (in some browsers like Opera 'Ctrl' and 'Alt' together) then press either single quote (post Snippet), right arrow (also post Snippet), up arrow (store Snippet) down arrow (remove Snippet from store). Some browsers allow you to make multiple text selections by holding down the 'Ctrl' key (again make sure you are within the comment body), you can use this to Snippet different parts of the same comment or different comments. A Fragment Snippet may look like this::snip_user_title_123_1_100:Note the last two digits represents the start and length. Quote fragments will try to render as is, however some of or all of the fragment may be stripped and displayed as plain text to prevent errors. In addition where there are nested Snippets the fragment will attempt to snap to the nearest block quote (the start of the rendered Snippet), within a proximity. It is recommended that you use the selection method to create Snippet fragments as manual input may not work as expected due the to how the behind the scenes measurement is worked out in order to be consistent as possible. In addition, occasionally certain content may not work terribly well with fragments. This is due to the fact that it may be too difficult to make accurate measurements. Some comments which contain media may automatically cause the Snippet Parser to disable fragment parsing to avoid badly formed fragments
    Snap Back
    You might have noticed 'snap back' to the right of each Snippet block quote. This will snap back to the original comment. If it is on the same page, the page will be scrolled so it is at the top. If it is elsewhere it will go to the page it is on. This is your way of verifying the content is as cited
    Comment Freezing
    Administrator may employ comment freezing. This is where comments that are Snippet can not be edited only appended. This ensures the content stays the same. If comment freezing is not employed Snippet will change as the comment they reference change.
    Administrators will almost certainly put limits of the number of Snippets displayed, and nested, however so long as you don't use Snippets in an excessive/unnecessary way you won't run into these limit too often. Snippets of whispers will only be visible to the sender and reciprocate, otherwise they will be masked with asterisks
    Valid Snippets escape the characters '_' and ':' when they are not intended to be separators or boundaries E.g.:snip_us\:er_ti\_tle_123:
    External Quotes
    Snippets is not for quoting anything that is not on the forum. If you want to quote some other content under 'fair use' please make use of the text formatters/filters (e.g. BBCode [quote][cite]user[/cite]...[/quote])

    grep is your friend.

  • Uploaded version 0.1 of Snippets.
  • Nice...

    Very, very nice!

    Works with my previous "quoted" messages and I like the style of the title line and the information displayed.

    Will continue to test it but now I can turn on QuikPost and keep all my quoted text.


  • Seems there may be a problem between Snippets and Yellow Fade. I could not find the Snippets menu until I turned off Yellow Fade and now I am able to click on the Snippets link and the Snippets menu will appear. With Yellow Fade active clicking on the Snippets link pastes the snippet into the active new discussion window without the extended menu ever appearing.

  • Thanks for letting me know

    grep is your friend.

  • Yep it is pretty obvious what the culprit is. It is not something entirely under my control.

    Various extension need to load when the page is rendered or DOM is ready. They are knocking each other off. Especially the event can only hold one thing at the time, and as there is no convention naturally there is going be conflicts. What you can do is pass a container, pushing all the function you want to load into this. That is essentially what jquery and mootols do.

    This all comes under the wider problem that is lovely and easy to create extensions for vanilla, yet the chance of extension conflicting with one another is quite likely. I have a bit to say on the subject of how to address this without sacrificing the freedom or being bogged down with configuration, etc. However I will ask mark what he is doing on that front for vanilla 2.

    I can update my extensions to have a decent domready script basically what JQuery uses. But that won't solve your problem. You will have to do the same for Yellow Fade.

    As yellow fade is quite minor you might as well monkey patch by replacing the functions.js with:
    // This technique is a combination of a technique I used for highlighting FAQ's using anchors // and the ever popular yellow-fade technique used by 37 Signals in Basecamp. // Including this script in a page will automatically do two things when the page loads... // 1. Highlight a target item from the URL (browser address bar) if one is present. // 2. Setup all anchor tags with targets pointing to the current page to cause a fade on the target element when clicked. // This is the amount of time (in milliseconds) that will lapse between each step in the fade var FadeInterval = 100; // This is where the fade will start, if you want it to be faster and start with a lighter color, make this number smaller // It corresponds directly to the FadeSteps below var StartFadeAt = 28; // This is list of steps that will be used for the color to fade out var FadeSteps = new Array(); FadeSteps[1] = "ff"; FadeSteps[2] = "ee"; FadeSteps[3] = "dd"; FadeSteps[4] = "cc"; FadeSteps[5] = "bb"; FadeSteps[6] = "aa"; FadeSteps[7] = "99"; FadeSteps[8] = "99"; FadeSteps[9] = "aa"; FadeSteps[10] = "bb"; FadeSteps[11] = "cc"; FadeSteps[12] = "dd"; FadeSteps[13] = "ee"; FadeSteps[14] = "ee"; FadeSteps[15] = "ee"; FadeSteps[16] = "ee"; FadeSteps[17] = "dd"; FadeSteps[18] = "cc"; FadeSteps[19] = "bb"; FadeSteps[20] = "aa"; FadeSteps[21] = "99"; FadeSteps[22] = "99"; FadeSteps[23] = "aa"; FadeSteps[24] = "bb"; FadeSteps[25] = "cc"; FadeSteps[26] = "dd"; FadeSteps[27] = "ee"; FadeSteps[28] = "ff"; //DOM ready borrowed (and botched). Thanks to John Resig (jquery.com) if (typeof DomReady == 'undefined'){ (function(){ var DomReady = window.DomReady = {}; // Everything that has to do with properly supporting our document ready event. Brought over from the most awesome jQuery. var userAgent = navigator.userAgent.toLowerCase(); // Figure out what browser is being used var browser = { version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], safari: /webkit/.test(userAgent), opera: /opera/.test(userAgent), msie: (/msie/.test(userAgent)) && (!/opera/.test( userAgent )), mozilla: (/mozilla/.test(userAgent)) && (!/(compatible|webkit)/.test(userAgent)) }; var readyBound = false; var isReady = false; var readyList = []; // Handle when the DOM is ready function domReady() { // Make sure that the DOM is not already loaded if(!isReady) { // Remember that the DOM is ready isReady = true; if(readyList) { for(var fn = 0; fn < readyList.length; fn++) { readyList[fn].call(window, []); } readyList = []; } } }; // From Simon Willison. A safe way to fire onload w/o screwing up everyone else. function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); } } }; // does the heavy work of working through the browsers idiosyncracies (let's call them that) to hook onload. function bindReady() { if(readyBound) { return; } readyBound = true; // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event if (document.addEventListener && !browser.opera) { // Use the handy event callback document.addEventListener("DOMContentLoaded", domReady, false); } // If IE is used and is not in a frame // Continually check to see if the document is ready if (browser.msie && window == top) (function(){ if (isReady) return; try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch(error) { setTimeout(arguments.callee, 0); return; } // and execute any waiting functions domReady(); })(); if(browser.opera) { document.addEventListener( "DOMContentLoaded", function () { if (isReady) return; for (var i = 0; i < document.styleSheets.length; i++) if (document.styleSheets[i].disabled) { setTimeout( arguments.callee, 0 ); return; } // and execute any waiting functions domReady(); }, false); } if(browser.safari) { var numStyles; (function(){ if (isReady) return; if (document.readyState != "loaded" && document.readyState != "complete") { setTimeout( arguments.callee, 0 ); return; } if (numStyles === undefined) { var links = document.getElementsByTagName("link"); for (var i=0; i < links.length; i++) { if(links[i].getAttribute('rel') == 'stylesheet') { numStyles++; } } var styles = document.getElementsByTagName("style"); numStyles += styles.length; } if (document.styleSheets.length != numStyles) { setTimeout( arguments.callee, 0 ); return; } // and execute any waiting functions domReady(); })(); } // A fallback to window.onload, that will always work addLoadEvent(domReady); }; // This is the public function that people can use to hook up ready. DomReady.ready = function(fn) { if(typeof JQuery != 'undefined'){ JQuery(document).ready(fn) return; }else if(typeof MooTools != 'undefined'){ window.addEvent('domready', fn) return; } // Attach the listeners bindReady(); // If the DOM is already ready if (isReady) { // Execute the function immediately fn.call(window, []); } else { // Add the function to the wait list readyList.push( function() { return fn.call(window, []); } ); } }; bindReady(); })(); } // The function that initializes the fade and hooks the script into the page function initFades() { if (!W3CDOM) return; // This section highlights targets from the URL (browser address bar) // Get the URL var currentURL = unescape(window.location); // If there is a '#' in the URL if (currentURL.indexOf('#')>-1) // Highlight the target DoFade(StartFadeAt, currentURL.substring(currentURL.indexOf('#')+1,currentURL.length)); // This section searches the page body for anchors and adds onclick events so that their targets get highlighted // Get the list of all anchors in the body var anchors = document.body.getElementsByTagName('a'); // For each of those anchors for (var i=0;i-1) // Add an onclick event that calls the highlight function for the target anchors[i].onclick = function(){Highlight(this.href);return true}; } // This function is just a small wrapper to use for the oncick events of the anchors function Highlight(target) { // Get the target ID from the string that was passed to the function var targetId = target.substring(target.indexOf('#')+1,target.length); DoFade(StartFadeAt, targetId); } // This is the recursive function call that actually performs the fade function DoFade(colorId, targetId) { if (colorId >= 1) { var target = document.getElementById(targetId); if (target) { target.style.backgroundColor = "#ffff" + FadeSteps[colorId]; // If it's the last color, set it to transparent if (colorId==1) { document.getElementById(targetId).style.backgroundColor = "transparent"; } colorId--; // Wait a little bit and fade another shade setTimeout("DoFade("+colorId+",'"+targetId+"')", FadeInterval); } } }

    grep is your friend.

  • Uploaded version 0.1.1 of Snippets.
  • domready implemented correctly

    grep is your friend.

  • Ok,

    Your explanation of the DOM and the patch is a bit over my head. I just started getting into this a few months ago. My solution was just to turn off Yellow Fade since it really isn't that important to me. Didn't mean to create more work for you just trying to help anyone out who could not find the drop down menu in Snippits. Thanks for the fixes. So all I need to do on patch is replace the function.js file in Yellow Fade with the text in your prior message?

    Also, since I installed the 0.1.1 version of Snippits I get a popup window when I try to read each message that says http://www.mylink.com say's "hi". I have to dismiss the window to keep reading the posts. Next post I click on the window say "hi" again. Very personable but annoying :-) It is gone if I turn off Snippits. It looks like a javascript alert.

    Any ideas about that?


  • oops

    grep is your friend.

  • Uploaded version 0.1.2 of Snippets.
  • Updated sorry about that. Yes the contents in the code above should be saved as the contents of function.js. It is an unofficial patch for what, as you say, is not a very critical functionality.

    grep is your friend.

  • Ok thanks!

    That took care of the popup. Installed the new functions.js but do not see the yellow fade effect. Snippets menu still works however. i will play around with this and see if it is something wrong on this end. I really don't need the fade.


  • If you have installed the webby chat extension you may notice that the snippets drop down menu is no longer functional when webby chat is set to the "page slide" mode. If you set webby chat to display over the page rather than slide the page the snippets menu again works. Not sure which extension is the problem but the edit and delete menus work in the "slide" mode but not snippets menu. I am just testing webby chat and am using the page management extension fix noted in the webby chat thread to get webby chat to work with page management.

    Just a heads up if your snippets menu stops working, take Webby chat out of the slide mode and see if that fixes the problem.

  • I've just installed Snippets in a brand new Vanilla 1.1.9 forum (empty database, no customizations, no extensions except Snippets and SetList) and I get this error on every page:

    Notice: Undefined index: QWIKPOST_MODE in /PATH/TO/ROOT/extensions/Snippets/default.php on line 50

    Any ideas what could be wrong?
Sign In or Register to comment.