Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is the code I have currently... I had to delete the rest to make it fit.</p> <p>-- I cleaned up the code quite a bit, but let me know if I need to clarify something as I'm not the best at documenting.</p> <p>This is the js that was named "so.js"</p> <pre><code>/* * author: craniumonempty * javascript/jquery for user dropdown over user flair for user sites (designed with stackoverflow, but should be easily adapted) * to be used in conjuntion with php * * Nothing to be called, it searches for all stackoverflow flair (as given by website with &lt;a&gt;&lt;img&gt;&lt;/a&gt;) on page * * This requires JQquery 1.5 or newer due to the $.getJSON().success() function call */ /* Minimal html to test: &lt;html&gt;&lt;head&gt; &lt;script type="text/javascript" src="jquery-1.7.1.min.js"&gt;&lt;/script&gt; &lt;script type="text/javascript" src="so.js"&gt;&lt;/script&gt; &lt;/head&gt;&lt;body&gt; &lt;a href="http://stackoverflow.com/users/540753/craniumonempty"&gt; &lt;img src="http://stackoverflow.com/users/flair/540753.png" width="208" height="58" alt="profile for craniumonempty at Stack Overflow, Q&amp;amp;A for professional and enthusiast programmers" title="profile for craniumonempty at Stack Overflow, Q&amp;amp;A for professional and enthusiast programmers"&gt; &lt;/a&gt; &lt;/body&gt;&lt;/html&gt; Note, jquery &gt;= 1.5 and tag (&lt;a&gt;&lt;img&gt;&lt;/a&gt;) with the stackoverflow site. It searches for that tag. Change the jquery if you want to search for something else. */ var fileStackGet = "loaduser.php"; // set this to the location of the php file var ano = 'rel="nofollow" '; // formats reputation score kind of like on the site "31.2k", "200k" function formatRep(r){ if ( r &gt;= 10000000 ) r = ((r/1000000).toFixed(1)+'').replace(/(.{1})(.{5})/,"$1,$2")+"m"; else if ( r &gt;= 100000 ) r = ((r/1000).toFixed(0)+'')+"k"; else if ( r &gt;= 10000 ) r = ((r/1000).toFixed(1)+'').replace(/(.{1})(.{5})/,"$1,$2")+"k"; else if ( r &gt;= 1000 ) r = (r+'').replace(/(.{1})(.{3})/,"$1,$2"); return r; } // shortens site name for output // e.g. 'http://somewhere.com/some_place_on_the_site/page.php' to 'somewhere.com/some_place_on_the_sit...' function formatSite(s,l){ if(l===undefined)l=48; s=s.replace(/^https?:\/\//,''); if(s.length &gt; l )s=s.substr(0,l-3)+'...'; return s; } // I didn't actually finish this function if someone wants to tweak it... // s[0] is about-me which gets cut off in 5 lines (didn't even start) // s[1] holds links in the cut off portion function formatAbout( a, ano ){ // this is a spaghetti hack (and a half)... I hope someone can make this more efficient a = a.replace(/[\s]+/gim,' ') // get rid of all unneeded space right away // since we are going to use the alt of the image (stackoverflow doesn't) we are putting it on the previous line .replace(/(?:\s*&lt;\/?(?:br|p)(?:\s*\/)?&gt;\s*)+((&lt;a(\s[^&gt;]*)?&gt;)?&lt;img\s[^&gt;]*&gt;(&lt;\/a&gt;)?)\s*&lt;\/?(br|p)(\s*\/)?&gt;\s*/gi,' $1[:p:]') .replace(/&lt;\/p&gt;|&lt;br(\s*\/)?&gt;/gi,'[:p:]') // find all the &lt;/p&gt; and all &lt;br&gt; tags to break at .replace(/&lt;a\s[^&gt;]*href=('([^']*)'|"([^"]*)")[^&gt;]*&gt;/gi,'[:a:$2$3]') // pull out &lt;a&gt; tags so we don't strip them .replace(/&lt;\/a&gt;/gi,'[:/a:]') .replace(/&lt;img\s[^&gt;]*alt=('([^']*)'|"([^"]*)")[^&gt;]*&gt;/gi,'$2$3') // get the alts from the imgs .replace(/&lt;(li)&gt;/gi,' ')// some might need space... not sure about other tags yet .replace(/&lt;[^&gt;]*&gt;/g,'') // strip all other tags and &lt;&gt; .replace(/\[:a:([^\]]*)\]\s*/g,'&lt;a '+ano+'href="$1"&gt;') // put the &lt;a&gt; tags back .replace(/\s*\[:\/a:\]/g,'&lt;/a&gt;') .replace(/[\s]+/g,' ') // double check space .split('[:p:]'); // split on the breaks // at this point we should have only &lt;a&gt; tags and it's split where we need to add breaks var len = a.length, l2, r = ['',''], n = 0, m = 0; var i,j,s,c,t=false; var h=0,hnum=3,hlen=18;//h is the amount of links currently in r[1], hnum is max h can get, hlen is the length of the text for ( i=0; n &lt; 5 &amp;&amp; i &lt; len; ++i ){ l2 = a[i].length; if ( l2 &lt; 1 ) continue; s=0;m=0;t=false; for ( j=0; j &lt; l2; ++j ){ // this is probably how I should have done above... // no real checks on &lt;a&gt; tag, just assuming start/end exist in order c=a[i].charAt(j); switch (s){ case 0: if(c=='&amp;'){//special char s=1; } else if (c=='&lt;') { s=2; t=!t; } else { ++m; } r[0] += c; break; case 1: if(c==';'){//end special char s=0; ++m; } r[0] += c; break; case 2: if(c=='&gt;'){ s=0; } r[0] += c; break; default:break;// should never end up here }; // unsure on per line, just guessing if ( m &gt; 50 ){ m = 0; ++n; } if ( n &gt;= 5 ){ if ( t ){ r[0] += "&lt;/a&gt;"; j = a[i].indexOf('&lt;/a',j+1); if ( j == -1 ) j = l2; } r[0] = r[0].substr(0,r[0].length-3)+"..."; break; } } // reusing m and s for different purposes below here if ( j &lt; l2 ) { // check if there are more &lt;a&gt; j = a[i].indexOf('&lt;a',j+1); while ( j != -1 &amp;&amp; j+1 &lt; l2 &amp;&amp; h &lt; hnum ){ s = a[i].indexOf('&gt;',j)+1; m = a[i].indexOf('&lt;/a',j); if ( s &gt; -1 &amp;&amp; m &gt; -1 &amp;&amp; s &lt; m ){ r[1] += a[i].substring(j,s); j=s; s=a[i].substring(j,m); if ( s.length &gt; hlen ){ s = s.substr(0,hlen-3)+'...'; } r[1] += s+"&lt;/a&gt; "; ++h; j = a[i].indexOf('&lt;a',m+4); } else { j=-1; } } } if ( n &lt;= 5 ){ r[0] += '&lt;br /&gt;'; } ++n; } while ( i &lt; len &amp;&amp; h &lt; hnum ){ j = a[i].indexOf('&lt;a',j); while ( j &gt; -1 &amp;&amp; h &lt; hnum ){ s = a[i].indexOf('&gt;',j)+1; m = a[i].indexOf('&lt;/a',j); if ( s &gt; -1 &amp;&amp; m &gt; -1 &amp;&amp; s &lt; m ){ r[1] += a[i].substring(j,s); j=s; s=a[i].substring(j,m); if ( s.length &gt; hlen ){ s = s.substr(0,hlen-3)+'...'; } r[1] += s+"&lt;/a&gt; "; ++h; j = a[i].indexOf('&lt;a',m+4); } else { j=-1; } } ++i; } return r; } // This returns '###' from 'http://stackoverflow.com/users/flair/###.png' function getId( s ){ s = s.substr(s.lastIndexOf('/')+1); return s.substr(0,s.indexOf('.')); } // returns individual css (may need to work on this) function css( user_id, top, left, width, height ){ var w='div#u_outerwrap'+user_id; return '&lt;style type="text/css"&gt;' +w+'{display:inline;margin:0;padding:0;border:none;}' +w+' span.badge1{background:url(data:image/png;base64,'+'iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sMCRA7KBn0AHUAAAAIdEVYdENvbW1lbnQA9syWvwAAAFZJREFUGNNjYMABGD8c5hfk5uZaxcjI4MLAwMDw/z/Dnq9fv4Ux/j4nuRsmCAP//zPsYfxzXvI/NqOYcNnB9P8/wx50wf//GfYwff36LQxZEmY5Ax0AADG6IrHAoV3lAAAAAElFTkSuQmCC);}' +w+' span.badge2{background:url(data:image/png;base64,'+'iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sMCRA7OXNEIIcAAAAIdEVYdENvbW1lbnQA9syWvwAAAEZJREFUGNO9jbENwDAMw2h9kJ96Q47MDdl8mLqkgDt4DSdBBCRoiMwcwIqIB8D2BqZqCXDyUi2rVPehs/nD9hYwq/zOucALY70ZZlPtha4AAAAASUVORK5CYII=);}' +w+' span.badge3{background:url(data:image/png;base64,'+'iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sMCRA7FDabfPIAAAAIdEVYdENvbW1lbnQA9syWvwAAAFNJREFUGNO9jbENwCAQxO4e0dFkJ2agyGAZghm+y0p0CF2qSK9ItHFpFwY28L7OI6fSSVYAkORzjWZRAgDJmlPpFmWMtnuYJP9KSW5zjRbjO8cPPDYBIdBekI7gAAAAAElFTkSuQmCC);}' +w+' span.badges{background-repeat:no-repeat;display:inline-block;height:11px;line-height:inherit;'+ 'margin:0 1px 1px 3px;overflow:hidden;vertical-align:text-bottom;width:6px;}' +w+' a img{border:none;}' +w+' .badgecount{color:#808185;padding-left:1px;}' +w+' div#user-menu'+user_id+'{-moz-border-bottom-colors:none;-moz-border-image:none;-moz-border-left-colors:none;'+ '-moz-border-right-colors:none;-moz-border-top-colors:none;background-color:#333333;border-color:#444444 #1C1C1C #1C1C1C;'+ 'border-radius:4px 4px 4px 4px;border-right:1px solid #1C1C1C;border-style:solid;border-width:1px;'+ 'box-shadow:0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 0 #727272 inset;color:#E3E3E3;'+ 'font-family:\'Helvetica Neue\',Helvetica,Arial,sans-serif;font-size:11px;line-height:1.2;'+ 'padding:10px;text-align:left;width:300px;z-index:320;}' +w+' div.um-gravatar{float:left;margin-right:8px;height:64px;width:64px;}' +w+' div.um-header-info a.um-user-link,' +w+' div.um-header-info span.mod-flair{color:#e2e2e2!important;font-size:18px;}' +w+' div.um-header-info span.mod-flair{margin-left:3px;}' +w+' div.um-header-info div.um-flair .badgecount{color:#e2e2e2;}' +w+' div.um-header-info div.um-flair .reputation-score{color:#e2e2e2;font-size:120%;font-weight:700;margin-right:2px;}' +w+' div.um-about-me{clear:both;font-size:11px;margin:5px 0;overflow:hidden;}' +w+' span.um-links a{font-size:11px;margin-right:8px;}' +w+' a,'+w+' a:visited{color:#b4d4ec;text-decoration:none;}' +w+' a:hover{color:#dcecf7;}' +w+' div#user-menu-wrap'+user_id+'{position:absolute;z-index:320;position:absolute;z-index:320;'+ 'top:'+top+';left:'+left+';width:'+width+';height:'+height+';}' +'&lt;/style&gt;'; } // bc is the badge count and t is the type function getBadge( bc, t ){ if ( bc &gt; 0 ){ return '&lt;span title="'+bc+' '+(t==1?'gold':(t==2?'silver':'bronze')) +' badges"&gt;&lt;span class="badge'+t+' badges"&gt;&lt;/span&gt;&lt;span class="badgecount"&gt;'+bc+'&lt;/span&gt;&lt;/span&gt;' } return ''; } // this is the usermenu that drops down function getUserMenu( user, ano ){ var about=formatAbout(user['about_me'],ano); return '&lt;div id="user-menu-wrap'+user['user_id']+'" class="user-menu-wrap" style="display:none;"&gt;' +'&lt;div id="user-menu'+user['user_id']+'" class="user-menu"&gt;' +'&lt;div class="um-header"&gt;&lt;div class="um-gravatar"&gt;&lt;a '+ano+'href=""&gt;&lt;div&gt;' +'&lt;img alt="gravatar image" src="http://www.gravatar.com/avatar/'+user['email_hash'] +'?s=64&amp;amp;d=identicon&amp;amp;r=PG" '+'style="width:64px;height:64px;visibility:visible;border:0 none;" /&gt;' +'&lt;/div&gt;&lt;/a&gt;&lt;/div&gt;'+'&lt;div class="um-header-info"&gt;'+'&lt;a class="um-user-link" '+ano +'href="http://stackoverflow.com/users/'+user['user_id']+'"&gt;'+user['display_name']+'&lt;/a&gt;' +(user['user_type']=='moderator'?'&lt;span class="mod-flair" title="moderator"&gt;&amp;#9830;&lt;/span&gt;':'') +'&lt;br /&gt;&lt;div class="um-flair"&gt;' +'&lt;span title="reputation score '+user['reputation']+'" class="reputation-score"&gt;' +formatRep(user['reputation'])+'&lt;/span&gt;' +getBadge(user['badge_counts']['gold'],1) +getBadge(user['badge_counts']['silver'],2) +getBadge(user['badge_counts']['bronze'],3) +'&lt;/div&gt;'+user['location']+'&lt;br /&gt;' +'&lt;a '+ano+'href="'+user['website_url']+'"&gt;'+formatSite(user['website_url'])+'&lt;/a&gt;' +'&lt;/div&gt;&lt;div class="um-about-me"&gt;'+about[0]+'&lt;/div&gt;&lt;/div&gt;' +'&lt;span class="um-links"&gt;'+about[1]+'&lt;/span&gt;' +'&lt;/div&gt;'; } $(document).ready(function(){ $('img[src^="http://stackoverflow.com/users/flair/"]').each(function(){ var failjson = false; // unsure if needed or works var timg = $(this); var user_id = getId(timg.attr("src")); var user_menu = new Array(); $.getJSON( fileStackGet + "?user_id=" + user_id, function(user){ if( user != null &amp;&amp; user["users"][0] != null &amp;&amp; user["users"][0]["user_id"] != null &amp;&amp; user["users"][0]["user_id"] == user_id ){ user_menu[user_id] = getUserMenu(user["users"][0],ano); }else{ failjson = true; } }).success(function() { if ( failjson ) { return; } var pos=timg.position(); pos.h=timg.height(); pos.w=timg.width(); var p=timg.parent(); // get &lt;a&gt; around &lt;img&gt; p.css("text-decoration","none"); p=p.wrap('&lt;div class="u_outerwrap" id="u_outerwrap'+user_id+'" /&gt;').parent(); p.html( css(user_id,pos.top,pos.left,pos.h,pos.w) + p.html() + user_menu[user_id] ); p.hover(function(){ $('div#user-menu-wrap'+user_id) .css("position","absolute").css("z-index",320) .css("top",pos.top).css("left",pos.left).css("width",pos.w).css("height",pos.h) .show() .animate({left:'-=10',height:'183',width:'330'},500); }, function(){ $('#user-menu-wrap'+user_id).hide(); } ); }); }); }); </code></pre> <p>the php (basically just gets user from stackoverflow (if not stored and is fresh), stores in file, and spits it out) it was named "loaduser.php"</p> <pre><code>&lt;?php /* * author: craniumonempty * php for user dropdown over user flair (designed for stackoverflow, but should be easily adapted) * to be used in conjuntion with javascript/jquery * * This simply gets data from site and stores in a folder. It polls the site according to $secconds_to_wait. * * This requires that the directory is writable. If not, then change $filename to point to a writable directory. */ if(!isset($_GET['user_id'])){exit;} $u=(int)$_GET['user_id']; // I set individual files because I was testing a few different users $filename = dirname(__FILE__).DIRECTORY_SEPARATOR."userdata${u}.txt"; $seconds_to_wait = 1200; // &gt;= 60 /* http://api.stackoverflow.com/1.0/usage Polling for changes should be done sparingly in any case, and polling at a rate faster than once a minute (for semantically identical requests) is considered abusive. */ function getStackUserDataStore($filename,$seconds,$nocheck=false){ $send = false; // check file for data if it is fresher than preset time // if it is return it and send, else return false file_exists($filename) &amp;&amp; $send = file_get_contents($filename); // no need to check if false, if it's at 0, something is wrong if ( $n = strpos($send,"\n") ) { $time = (int)substr($send,0,$n); if ( $nocheck || time()-$time &lt; $seconds ) { $send = substr($send,$n+1); } else { $send = false; } } return $send; } function setStackUserDataStore($filename,$data){ // no need to check for false directly, if it writes 0 bytes, something is wrong if ( !file_put_contents($filename,time()."\n".$data) ) { return false; } // update data for user return true; } function getStackUser($userid,$filename,$seconds=120){ if( $userid &lt;= 0 ){ die("getStackUser: user_id&lt;=0"); } if( $seconds &lt; 60 ){ $seconds = 60; } if ( !($user_data = getStackUserDataStore($filename,$seconds)) ) { ob_start(); @readgzfile("http://api.stackoverflow.com/1.1/users/".(int)$userid); $user_data = ob_get_contents(); ob_end_clean(); if ( $user_data == '' ) { // probably can't connect, try to get datastore with no check $user_data = getStackUserDataStore($filename,$seconds,true); } else if ( !setStackUserDataStore($filename,$user_data) ) { // unable to store... should do something die("getStackUser: Unable to write data"); } } return $user_data; } if ( !($user_data = getStackUser($u,$filename,$seconds_to_wait)) ) { // something went wrong die("getStackUser: Unable to get user data"); } echo $user_data; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload