Create your own WebTop in php/js in no time

They are everywhere: protopage, pageflakes, netvibes et al are free, easy to use -as long as you have a powerful browser- and moderatly eye-pleasing.

SO?

A couple months ago, I wondered how long it would take me to build my own ‘WebTop’ (You can play with it here). The challenge would be to get it to a satisfactory state over a week-end.
Of course, I decided to use existing open-source code for the applications’ primary needs.

These needs being:
1. Users should be able to play with the application without being logged in
2. They need to know that if they do log in, the state of their webtop will be memorized for their next session
3. Webtops are windows-based; webtops’ dimensions are virtually unlimited and windows can be laid out anywhere in that immense space.
4. Also, windows may need to be iconified and when they are, displaying a relevant icon would provide great visual clues.

I decided to use these four libraries:

* Sebastien Gruhier’s Prototype Window
* Mohamed Ahmed’s Users Login System
* Michal Migursky and Matt Knapp’s Json class
* InputParser.php, which I extracted from my very own nextBBS‘ source tree

Oh, and the wonderfully simplistic red icons are the creation of P.J. Onori (thanks Sam!).

Of course, you could obviously use any piece of technology you like; I simply picked these four because they allowed me to hit the ground running.

HACKING AWAY

The one piece I heavily added to is Prototype Window.
For instance, I added a drop-down contextual menu to windows, activated when clicking on the new ‘menu’ button, next to the ‘close’, ‘expand’ and ‘iconify’ buttons.
home.clicdev.com Contextual Menu
These three menu items let the user:

1. Change the background color of the iconified version of the window
home.clicdev.com Color Picker
Let’s say…purple
home.clicdev.com Iconified
Well…it *is* purple

2. Change the window’s overall theme
home.clicdev.com Window Theme 1 home.clicdev.com Window Theme 2

3. Reload the content of the window

To create these menus, I went with my usual method of creating HTML elements that I position and display on demand, instead of re-creating them every time.

<p class="skin0"></p>
<p class="menuitems"><img src="http://nexus.zteo.com/wp-admin/themes/day.gif" align="left" />; Icon Color</p>
<p class="menuitems"><img src="http://nexus.zteo.com/wp-admin/themes/day.gif" align="left" /> Window Theme</p>
<p class="menuitems"><img src="http://nexus.zteo.com/wp-admin/themes/loop.gif" align="left" /> Reset</p>

 

I had to further modify the code of Prototype Window because it did not offer anything for iconified windows.
What I am doing is hide the actual window, create a square window that is a representation of the hidden one and slap a relevant icon in the middle of it -if I manage to retrieve one-.
About this icon: I simply query the server hosting the iconified application for its default favicon and download it for caching purpose - see below.

To implement these features, I only added a few hooks to window.js, leaving Sebastien’s code relatively untouched, and piling up my dirty code in cfr.js instead.

BEHAVIOURS

* I had to add a hook to catch the fact that a user is leaving the current webpage, asking them whether they really wish to do this and canceling the event if they do not.
This was easily implemented using Javascript’s onbeforeunload(), which happens to work in all the browsers I tested.

$obfulstr = "onbeforeunload="return 'For some reason, you are about to leave this page:nIt could be your decision or an application, such as Yahoo, trying to force its way out.nMAKE SURE THAT YOU SAVED YOUR DESKTOP!';"";

* The login window itself is simply Mohame’s login code embedded within an iframe, which in turn I turned into a CSS window.
home.clicdev.com Login Screen

?View Code JAVASCRIPT
function cfrNewLogin()
 
{
 
  _loginwin = _doOpenWindow('Login', ROOTPATH+'login/', false, 340, 240);
 
}

AJAX

As you can imagine, Ajax is used fairly heavily. Here is how: all frontend queries are channeled through a method in cfr.js, called _talkToMe()
This method uses Prototype’s Ajax implementation -but you could use any other implenentation here- to contact the backend.

?View Code JAVASCRIPT
case 'minimize':
 
  var iconcolor;
 
    if(win &amp;&amp; win.element.getAttribute('iconcolor'))
 
      iconcolor = win.element.getAttribute('iconcolor');
 
    else
 
      iconcolor = '-';
 
    var myAjax = new Ajax.Request(
 
      'backend/index.php',
 
      {
 
        method: 'get',
 
        parameters:
 
          'action=minimize&amp;id='+id+'&amp;title='+prepare(message)+'&amp;iconcolor='+prepare(iconcolor)+'&amp;url='+prepare(url),
 
onComplete: getMinimizeReply
 
      });
 
    break;

The backend class BE, defined in index.php, extends BackEnd which itself implements low-level communications using Json and/or XML.
The backend has knowledge of the code of the various widgets requested by the frontend and has the ability to retrieve favicons from other websites. The latter is done through the very straightforward use of fopen() and file_get_contents().

// Build path to favicon.ico
 
preg_match("/^(http://)?([^/]+)/i", $url, $matches);
 
$prepath = $matches[1].$matches[2];
 
$path = $prepath.'/favicon.ico';
 
// Does this guy exist?
 
$bFound = false;
 
$f = @fopen($path, 'r');
 
if($f)
 
{
 
  // /favicon.ico
 
  @fclose($f);
 
  $contents .= @file_get_contents($path);
 
  axlog("FOUND CONTENTS=".strlen($contents));
 
  if(strlen($contents)&gt;0)
 
    $bFound = true;
 
  }
 
  if(!$bFound)
 
  {
 
    // Get page contents
 
    @fclose($f);
 
    $contents .= @file_get_contents($url);
 
    $c = preg_match("//i", $contents, $matches);
 
    if($c &gt; 0)
 
    {
 
      $s = &amp;$matches[0];
 
      $c = preg_match("/href=(.+?)(['"&gt;])/i", $s, $matches);
 
      if($c &gt; 0 )
 
      {
 
        $s = str_replace(array("'", """), array('', ''), $matches[1]);
 
        // Build new URL
 
        if(strpos($s, '://')===false)
 
        {
 
          if($s[0]=='/')
 
            $path = $prepath . $s;
 
          /** @todo 'else : relative path' */
 
          axlog("Found relative favicon @ $path");
 
        }
 
        else
 
        {
 
          axlog("Found absolute favicon @ $path");
 
          $path = $s;
 
        }
 
      }
 
      else
 
        $path = 'themes/window.gif';
 
    }
 
    else
 
      $path = 'themes/window.gif';
 
  }

DATABASE

Since we are using Mohamed’s login script, database connectivity comes for free.
Note that his script uses one table: maaking_users
We need to add our own two tables:

maaking_session - each entry in this table will be a user window:

CREATE TABLE `maaking_session` (
 
`id` int(11) NOT NULL auto_increment,
 
`userid` int(11) NOT NULL default '0',
 
`url` text,
 
`useTop` tinyint(1) default NULL,
 
`useLeft` tinyint(1) default NULL,
 
`top` int(10) default NULL,
 
`bottom` int(10) default NULL,
 
`left` int(10) default NULL,
 
`right` int(10) default NULL,
 
`title` text,
 
`width` int(10) default NULL,
 
`height` int(10) default NULL,
 
`hidden` tinyint(1) default NULL,
 
`iconcolor` varchar(10) default NULL,
 
`contents` text,
 
`usertheme` varchar(16) default '',
 
PRIMARY KEY  (`id`),
 
KEY `userid` (`userid`)
 
);

and maaking_favicons:

CREATE TABLE `maaking_favicons` (
 
`id` int(11) NOT NULL auto_increment,
 
`url` varchar(255) NOT NULL default '',
 
`icon` text,
 
PRIMARY KEY  (`id`),
 
KEY `url` (`url`)
 
);

This is it for now. Download the zip package, play with it, let me know what you think or if you have any questions!

If you enjoyed this post, make sure you subscribe to my RSS feed!

Similar Posts:

There are currently no comments highlighted.

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

Thank you for the spent time. Very useful information

Sorry, sex shop bdsm
, sna,

Sorry, bdsm slave position
, fntqsf,

gdfgdf fjhgjhg gfdgdf ghfhgf nude teenage black girls

dfgfj gfhdf dsfgdsfh jhgfjhg fg h lolita comics xxx

gfdgs gsafds fgfdsghf asfsd galleries teens bbs

gdfgdf gdfgdfs gdfg sdg gdfgsd www youporn comn

gdfgdfg gdfgdsf gdfgdsf gdsfg similar to pornotub

dfgdf gdfgdsf gdfsgsdf gdfsgdsfg free ring tones for sprint pcs

sdfdasf dsffsadf sdfasdf dsfasd free motorola ringtones v400

dfsgdsfg dsfgdsg dsfgdsfg sdfg best airfare

visit this link please, haveing sex, 7520,

Wonderful and informative web site.I used information from that site its great.u

4n0lH7 hi nice site thx http://peace.com

Oh, and did not know about it. Thanks for the information …

Hi, all. Nice site…I really like your site ! Good job man.

The site\’\’s very professional! Keep up the good work! Oh yes, one extra comment - maybe you could add more pictures too! So, good luck to your team!

I like that!t

Hey All ! ! !
Want to spend your vacation to be remembered for long?
Tourism
help you carry out your wishes !

This site was very useful for me.

Great tutorial.\

Greetings!..
alaska fishing lodge kodiak alaska fishing lodge booking

I have your site for its useful and funny content and simple design.l

I have your site for its useful and funny content and simple design.T

Your work is marvelous!!u

Hi! Nice site!

That’s great stuff ! (except for the PHP short open tags used, of course ;)
I can easily imagine this used as a start for something in any community site.

Quite an app you have there, though I don’t understand half of it. The icons are Bitcons btw, http://somerandomdude.net/srd-projects/bitcons/

cheers.

[...] Chris Ravenscroft decided to build his own webtop in PHP and JavaScript and has written up the experience. [...]

[...] Chris Ravenscroft decided to build his own webtop in PHP and JavaScript and has written up the experience. [...]

[...] TagBulb: Tag Search SimplifiedProjax: PHP Generators for Prototype and Script.aculo.usCOMET with PHPAJAX MVC (so to speak)Eliminating async Javascript callbacks by preprocessingAjax-based PHP Grid Acquired, Soon to Open SourceAdding AJAX to a Website step by step, Part IIAdding AJAX to a website step by stepBuild an RSS Feed Reader using Ajax and PHPPHPClasses.org Ajax UpgradeCreating an Ajax Login Page with Dojo/Zend FrameworkMike Potter Builds a Flash-y Ajax SiteXMLHttpRequest Quirks and PHPAJAX pagination made simple (with Symfony)Integration of Spry and PHP/MySQLAdobe Spry and PHP/MySQLMODx CMS - An Ajax/PHP Content SystemGCalendar: Accessing Google Calendar from JavaScriptjsFlickrSlideshow: Sliding through FlickrPredictions: Ajax in 2007Porting Prototype Enumerable functions to Mootools Array objectsApollo is seriously coolGWT Compilation DetailsBackbutton OverloadingJavaScript Variable Dump in ColdfusionGoodbye Google SOAP APIFree Ajax Ringtone MakerUsing CNAMES to get around browser connection limitsjQuery updates: 1.0.4, documentation, and peopleOpenKM: Ajax Document Management SystemAjax Cookbook: Helpful JavaScript tipsPhobos and DojoTweebox 1.0: Browser based choose-your-own-adventuresGoogles Rounded Corner GeneratorBill Gates on Web AppsGaming industry 2.0Building a Fish Eye MenuLe Web 3 fails, politicians and organization to blameGoogle Web Toolkit 1.3: Open Sourcetooltip.js version 0.2ThinWire 1.2 RC 1 ReleasedMooTools for the Rest of UsDrawling lines in JavaScriptTestable Ajax SeminarhtmlPlayground: GWT based reference guideMiro: light-weight JavaScript rendering engineWhy most startups suck - on doing better through designDOMTool: Given HTML generate DOM methodsBlack Background TechniqueGoplan updatesIs Converging Towards the Desktop Good?MochiKit.Animator: New Animation in MochiKitDOM events in the Microsoft Ajax Library formerly known as AtlasWeb Design is 95% Typographymoo.fx 2.0: a whole new mooingWhy the “online office” won’t work for nowAmberjack: JavaScript Site Tour CreatorIntegrating Maps into Your Java Web Application with Google Maps and AjaxSSLBridge: Ajax Samba ClientDeath of the Desktop by Aza RaskinJSONRequest ProposalGoogle Coop: Vertical SearchingPractical Design in Ajax by Sarah Nelson and David VerbaClorox - Shared Memory Abstraction for AJAX ApplicationsOn clever experiencesWidgets, or the Blog as christmas treeGoogle Gadgets for your siteGraft: Making Javascript DOM a Piece of CakeBenchmark: DOM vs. innerHTMLYUI: Setting the record on library file sizeFlapjax: Functional JavaScriptMootools Accordian TutorialSmooth Slideshow 2.0Tracking Ajax Requests in AnalyticsDetecting IE7+ in JavaScriptGoogle buys YouTube, internet wonders whyThe State Of Web Development - Ajax set to surpass Flash in ‘07“Don’t Waste Time” with Graphical Ajax SolutionsSearchMash: Googles playpenDynamic Graphics in the BrowserWeb 2.0 eCommerce - It’s What Shoppers WantYahoo! Browser-Based AuthenticationThe Dangers of Cross-Domain Ajax with FlashGoogle Reader Fresh LookTranscorners: Because you are obsessed with rounded cornersbytefx: simple effectsLessons in JavaScript Performance OptimizationDojo Spreadsheet WidgetTransparent custom corners and borders, version 2Transparent Messages in JavaScriptFull RSS feeds - I was serious the last time, too.Ajaxium 2.0: ASP.NET Ajax ContainerWatching Your Words2020 Internet VisionBehr: Rich Color ChoosingIntra-iframe Message PassingMan Bites Mainstream MediaTop 8 Ajax evaluation criteriaUPS Begins Talks with TeamstersCDW, Welcome to the Fast FiveOPML Icon ProjectWritely Getting TightlyGood Looking Deal HuntingMore Lists; Less ThinkingLaunching web-applications quietlyAdvertising Beyond the Web: Heavyhitters take to TVNewsGator Desktop Sync for IE7 and VistaObjectifying JavaScriptUsability Report CardThe beauty in (user) experienceMS Live.com: Ajax Image SearchMicrosoft JavaScript Perf. TipsLighter Fare: Craigslist eCommerce”Atlas” 1.0 Naming and RoadmapJavaScript Closures for DummiesKeep Your Customers Updated with RSS FeedsAjax IE Caching IssueDramatically improved IE7 JavaScript performanceScope in JavascriptTIBCO GI Supports FirefoxWeb Development Tools for the Power DeveloperMooTools ReleasedStop using the “beta” labelGoplan is on, invites are outWeb 2.0 and the necessity of failureAJAX-based One-Page Checkout: VideoWhy Ajax?Facebook Gets Egg on its Face, Changes News Feed FeatureChosenVIP to Launch Exclusive Social Networking SiteBreaking: Xanga Fined $1 Million For Violating Children’s PrivacyvSocial Gets Funding for More Video-SharingTreemo Launches - YouTube Plus Photobucket on Your PhoneFaketown 2.0 - The Next Habbo Hotel?Wink 2.0 Launches, Becomes a Social NetworkCrowdstorm and Dovetail.tv Launch TodayFrom Barcamp to ShiftRojo Acquired by SixApartThe Facebook Backlash BeginsMotionbox Gets FundedJavaScript ThrobberSoapbox’s Social Network For ReviewsApocalypse 2.0 - A New Era of FragmentationYouTube IPO?HyperScope: From the past to the futureMultiply to Announce Social Bookmarking ToolBridging Java Swing with AjaxDojo’s Deferred APIGoogle Image Labeler: Collaborative Tagging GamePoliticians Come To Facebook for Election 2006Beginning Ajax with ASP.NETTagged Rolls Out New FeaturesJavaScript Persistent Object Notation (JSPON)GWT + JSF = G4jsfPageviews are ObsoleteBlog It with WLW from FirefoxBookMooch’s Social Network for Book LoversWebshots ReloadedMySpace Audio Comments from MyChingoHotspottin Launches Social Network For HotspotsMore Developers Are Using AJAX in Emerging Markets Than in North AmericaKaboodle Gets Widgetized!Vdiddy Aggregates YouTube, Metacafe, MySpace VideoGoogle Pitching Services to Small and Medium Sized BusinessesGeek in the ParkTechCrunch UKCorporate collaboration softwareThe Future of NetvibesjQuery 1.0 ReleasedProfiling and Optimising Ajax ApplicationsFilteringTable dojo WidgetWindows Live Writer PluginsLightbox using iFrames instead of AJAXIs Google Still The Ajax King?If blogging is a conversationFacebook Ads, Powered by MicrosoftGrouper Acquired by Sony For $65 Million in CashZero Kode, Visual Designer for ZKFacebook Notes - Facebook Adds BlogsParis Hilton Videos Now on YouTubeTraineo Launches Social Network for Weight LossCrazyEgg LaunchesThisNext Launches Shopping Social NetworkAmateurIllustrator Takes on DeviantArtFeedpass Takes Aim at MySpace BlogsUnivillage Launches UK FacebookFriendster Makes Friends with $10 MillionAjax Login with AcegiDon’t be afraid of GoogleBattleOut Puts Photos Head-to-HeadPhotobucket Raises Millions MoreTwango is YouTube for EverythingAsk.com’s Binoculars - Help or Hinderace?Nick Lachey’s Celebrity Social Network - Flop or YFly?YouTube To Host Music VideosBurrp Launches Social Reviews Site TodayTakkle - Social Network For High School SportsBlueOrganizer - a Fresh Look, and Codes for MySpaceKiko for Sale on eBay For $50,000MySpace Video vs YouTube - Who’s Winning?Trailfire Launches Advanced Social Bookmarking ToolSurvey of Javascript Inheritance TechniquesWindows Live Writer (Beta)AjaxitaggingBlogger Releases New Beta VersionKevo Launches - Wikipedia Meets Paris HiltonInterview: Google’s Bruce Johnson on the new GWT 1.1 ReleaseIntroducing LaCo (or AJAX for the non-programmer)Drawing the line on picking clientsUnobtrusive Javascript and Ajax for RailsTypePad Launches TypePad MobileJavaScript Tricks And Good Programming StyleSXSW Panel PickerCross-Domain Ajax InsecurityReal Time Satellite Tracking (with Google Maps)Crowdstorm - Social Networking Meets ShoppingHow to Design a large AJAX ApplicationRSS EtiquetteTripHub Launches Group Travel SiteAdoppt - Another Generic Social NetworkFanpop Launches Social Network for FansJavaScript Model-View-Controller with Dojo toolkitCross Domain XMLHttpRequestCEO Blogging at WordCamp 2006Can Your Programming Language Do This? Javascript Can.AOL Video Is Live - and it’s BIG!Del.icio.us Adds Network Badges - Now Officially a Social NetworkThe Dangers of Browser DetectHow To Load And Parse XML Data Without ActiveXWhat’s So Special About Ajax?FlickrMap V2 Released - Put Flickr Maps on Your BlogWhat we think of Web 2.030Boxes Releases the822, a New People Search EngineToo Much AJAX?CREAMaid One-Ups PayPerPostWindows Live Spaces Goes Live, Succeeds MSN SpacesWeb 2.0: Why Tufte is wrongYahoo! yodelsWeb 2.0 desktop-style apps: Why no local drafts?One month to Barcamp Portugal!ClipShack Owner Gets $2MLook Out Dell - Sutori is ComingHosting providers, meet reality checkEons Launches - You Have 5 Unread Death AlertsYouTube Now “More Popular” than MySpaceMake your own kind of music at SingShotCSS: The Tech Ajax ForgotGmail and content findabilityReading on a screen is a lousy experienceWeatherBug Launches YouTube for WeatherCNN Exchange - CNN’s Answer to YouTubeCooqy Brings eBay to MySpace - and Finds a Workaround to the MySpace Update?Hating Web 2.0: Privacy vs. ConvenienceSingShot Launches the YouTube of KaraokeSpyMedia 2.0 Launches - Sell Your Photos on Blogs and MySpaceAptana: New Web IDE in BetaMySpace Screws Up Again: Accounts Being Deleted?Is Ajax development slowing down?Snapvine Adds Voice Comments To MySpaceCross-site Ajax (from OSCON 2006)Prototypify: Running Prototype code with legacy codeAjax and the Spring Framework with TIBCO General InterfacePains of document.domain in FireFox 1.5Cyworld US is LiveSlate Reddit ReleasedJavascript Boot Camp TutorialSnocap Launches Linx - Napster Founder Selling Unprotected MP3s on MySpaceMeebo IM Now in NetvibesMenuTree Serves Up Take-Out 2.0Netscape HackedYouTube Is Not For SaleSayNow Adds Mobile Shoutouts To MySpace MusicSportsMates Launches - Sports Themed MySpaceSneakerplay’s Sneaker-Based Social NetworkPlanning an Ajax Boot CampNokia and Backbase cooperate on Mobile AJAXFacebook Giving Away Free iTunes MusicOtavo Launches - Yahoo Answers, Friendster and del.ici.ous Rolled into OneGoplan updatesRediscovering Flyweight for JavascriptStylehive Gets FundingImageKind Launches - CafePress for Wall ArtGPokr: Ajax Poker AppLink Thumbnail: Photo Mouse OverBiggest AJAX problemBreaking User Interfaces for Fun and ProfitDabble Searches YouTube, MySpace Video, Metacafe and MoreNextcat - MySpace For EntertainmentDiigo Launches, Nobody CaresSocialtext Open Launches - Commercial Open Source WikiTeamSugar Launches Social Network for WomenFolkd is a Half-Decent Digg Clone (Finally)Gotuit - YouTube for Premium Content?Safari: Browser.Back + AjaxTechnorati Turns Three, Releases Major UpdateAdvanced Box Model TestingXN Test: The next Unit Testing project?MySpace Goes OfflineCSS Browser SelectorGoogle PaintA Java-based HTTP Proxy for AjaxInterview with Jakob NielsenIf you can’t build a community, buy oneDeclarative AjaxJson.NET 1.1: Converting between XML and JSONThe Importance of Maintainable JavaScriptIs AJAX Accessibility a major issue?Free AJAX Training CourseStop trying to be MyspaceAjax as a Remedy for the Cacheability-Personalization DilemmaJ2EE and AJAX: AJAX with ServletsTwo Key Challenges for Ajax Adoption that We Have IgnoredA Basic Approach to Server-side Data Validation with AJAXGo forth and APITuesday Morning RoundupAjax Activity IndicatorsWeb API authentication for mashupsOPML IconExplaining AJAXEcho2 Widget PanelSlightly ThickerBoxJSON.NETDigg and the wisdom of crowdsJson.NET: Library to help with .NET - JS communicationuniAjax: an ajax framework focused on browser supportPayPerPost: Right or Wrong?Atlas June CTPBarcamp Portugal, more detailsRelay: Ajax File ManagerDojo Available in Ning ApplicationsIntelliJ IDEA Google Web Toolkit SupportGoogle CheckoutPrivate and Public Members in JavaScriptJavaRef: Ajaxified JavaDocSafari gets a Javascript debuggerInterview with ZK Creator Tom YehSpeeding up Prototype’s $$ SelectorLondon Tube Route FinderWeb 2.0 Opinions - Oh How They DifferSmall Business & Web 2.0 Marketing Chris Ravenscroft decided to build his own webtop in PHP and JavaScript and has written up the experience. He built on: [...]

[...] Clic!Dev, ‘Tate, and many more projects! » Blog Archive » Create your own WebTop in php/js in no time (tags: javascript php ajax webtop) [...]

[...] Clic!Dev, ‘Tate, and many more projects! » Blog Archive » Create your own WebTop in php/js in no time Posted in bookmarks | Trackback | del.icio.us [...]

[...] Create your own Webtop in PHP and JavaScript Chris Ravenscroft decided to build his own webtop in PHP and JavaScript and has written up the experience. [...]

[...] Chris Ravenscroft decided to build his own webtop in PHP and JavaScript and has written up the experience. [...]

[...] Chris Ravenscroft decided to build his own webtop in PHP and JavaScript and has written up the experience. [...]