Aptana will build off of its IDE and AJAX success with its new technology. Read the full story.
Learn more about Aptana Cloud, an "Elastic Application Cloud" that's ideal for Web developers who use scripting languages.
Join the early access program.
Following are the convenience functions that help make the magic happen. The first function is addElementToPage(). It very simply just creates an H2 tag and sets the title and a DIV tag which contains the contents of the fetched element:
This next function, getDocumentFromURL(), is the one that does most of the work. (I found some good info on the subject of HTML to DOM here: http://jszen.blogspot.com/2007/02/how-to-parse-html-strings-into-dom.html) It first goes and retrieves the remote page. Then it creates a 'document fragment' from the contents of the fetched site. That fragment is then added to a dynamically created IFRAME. Finally, the Document object from the IFRAME is fetched and returned. In short, we can pass in a URL, get the string value, place it into an IFRAME, then pull out the resulting Document object so that we can work on it.
This final function was found at http://www.dustindiaz.com/getelementsbyclass/ and walks a node looking for an element with a specific class name. It was used in the case where elements don't have ID's, so a class name is used instead.
What's exciting about this sample is that it is relatively simple, uses the full power of server-side JavaScript and more importantly, Jaxer's cool server-side DOM capability to enable real 'DOM scraping'. Once window object creation is finished in Jaxer (real soon now), then you'll be able to fetch remote pages, execute their integrated code, then proceed to fetch out items from the resulting DOM.
In this example, (the first in a series) we're going to build a simple voting tool, using a single page of DHTML. The implementation is quite basic but covers a good few examples of how to use Aptana Jaxer in real world situations, such as :
This example was written as a single page webapp. You could remove the Javascript to another file and make it all unobtrusive if that is what gets you excited, but I'm just using an inline script tag, as the code is only about 30 or so lines long. Also in Jaxer we could have easily implemented this using Jaxer's seamless ajax callback mechanism but for the purpose of this example we'll stick with a traditional form post.
Let's get started. Most folks reading this should be familiar with the standard blog/portal poll, where you are presented with a set of choices.
and once you have voted you get to see the current results of the voting.
In our example we allow multiple votes per user but you can easily change that by just commenting out a single line of code.
One of the interesting features of this application is that, by using server-side DOM manipulation in Jaxer, you can remove any unwanted content before it is sent to the client browser. We use this to hide the vote results until the user has voted
This is a useful technique for permission based forms where, for example, you may want remove the credit card details unless the user has established the correct permissions and been validated by the server.
So let's jump in and have a look at the code used to make this work.
Above is the contents of the HEAD element. Just the usual suspects, setting the title and some simple CSS stuff. The only interesting part is at line #3, where we load the jQuery library on the server, because we intend to do some serverside DOM manipulation before the page is sent to the client.
The runat='server' attribute tells Jaxer to load this javascript library on the server.
The autoload attribute is a recent addition to Jaxer, and it instructs Jaxer to load that page and keep it cached as preparsed bytecode (for faster library loadtime) for any future calls to this page, including callbacks.
In the body of the document we have a simple form which we will dynamically populate on the server. The form will post the vote to itself on the server.
We are marking up the DOM content with the classnames 'voter' and 'nonvoter' to identify content that is specific to a user's status, and make it easily accessible using jQuery on the server.
The first dozen or so lines are simply creating a DB and preparing a schema for use.
So we've connected to the database (which was automatically created if needed, how convenient!) and set up the schema and initial content we expect. We also setup an Array (questions) containing the questions for the voting poll
Next we need to check the session value we are storing (status) to determine whether this user has already voted, and then check to see if the form data for the vote is being posted. Then, if we are actually voting, we write the vote to the database and set the user status to 'voter'.
When we write the vote to the database, we grab the sessionID and the remote IP address and write those out with the vote data, this will let us enforce single voting later if we need it.
Finally query the database to get the current vote counts, remembering to subtract 1 from the total to account for the dummy rows we inserted to seed database and prevent any nulls from appearing in the results totals.
Now we build the DOM, to do this we issue a query to the DB to get the current vote tally.
Using E4X - ECMAScript For XML as a simple templating tool we create the DOM with the nodes populated according to our dataset.
One of the nice features of server-side javascript with Jaxer is that you have access to all neat things built into Mozilla without the worry of client side browser support, which enables reliable use of the advanced features of the Javascript language.
If you look closely at the code below you'll notice we use a simple syntax for variable substitution using curly braces containing javascript code inside the E4X assigments. This allows us to use this for templating as long as we are creating valid XML nodes.
So the document now has a DOM that has been populated with the content for BOTH voters and non-voters. We use a little jQuery magic to remove the elements we don't want presented to the user.
In this way the user will EITHER see the form with the question and the submit button
OR the current voting results data.
Now we set the session variable status to be the current status of the user as they have either voted or not.
Finally as the page that is served has no further dependency on Jaxer once it leaves the server, we tell Jaxer to not bother injecting the client framework. Normally the client framework would be automatically inserted as a script tag in the outgoing HTML, but our simple example doesn't need to communicate back to the Jaxer server, as it contains no server callbacks.
So there you have it, a simple poll on a single page, using many of Jaxer's cool features.
The full code and supporting files for this article are available here
Aptana Jaxer has been updated to 0.9.5 providing increased performance for server-side JavaScript and a host of other enhancements to make End-to-End Ajax development easier.
Aptana Studio users can get the latest via Help > Software Updates. Otherwise, download the latest now.
One of the common web tasks that always seems to involve a lot of arcane knowledge of backend systems, is how to upload files. Like most systems, Aptana Jaxer uses the post/receive model, where a web form is posted to the server, and the target of that form will receive and process the content. Where Jaxer makes this really easy is that it is all done with regular JavaScript and HTML. No special enviroment vars, excessive string processing, or finding handles to oddly named temp files is required.
All you need is a form to present to the user, which contains an input element of type upload, and an HTML page to receive the submitted form containing a "runat=server" script block that retrieves the data from the request. You could have the form and the recipient be the same page, however in this example I'll use two files for clarity. As an aside in Jaxer you can actually send the form directly to a JavaScript function living on the server but we'll look at that configuration in a future blog entry.
This example upload form simply allows you to select up to 2 files for upload from the local filesystem. Pressing 'upload' posts the contents of that form to an HTML page containing the JavaScript shown later.
The form will look like the following when viewed in a browser. Pressing the browse button will present you with a file selection dialog, or you can type the path into the input box directly. I've used 2 file slots in this example to demostrate that the files passed in are available as part of an files array contained in the request object (a JavaScript representation of the HTTP request) and are accessed like any other JavaScript array.
'upload' sends the selected file(s) to the server.
To receive the data from the form when submitted we put some Jaxer code into the page the form will be submitted to. The code below should be in script block with a runat = 'server' attribute, which makes the code run serverside and doesn't present it to the client so you don't expose any serverside filenames or folder structures.
The data posted by the form is available within the Jaxer.request object.
For the purposes of this example we are specifically interested in the Jaxer.request.files array which contains an array of Jaxer.Request.FileInfo objects, one for each file posted with the form.
The Jaxer.Request.FileInfo object contains some useful properties describing the file, such as fileName, contentType, etc.Uploading two files from my filesystem from the form in this example would return a page of output like below. We have uploaded the file to same location as the submission.html file used as the form action in the originating HTML.
Saved to : C:\aptana\JaxerDev\public\work\bar.txt original filename : bar.txt temp filename : C:\aptana\JaxerDev\tmp\tmp contentType : text/plain size : 15754 Saved to : C:\aptana\JaxerDev\public\work\foo.txt original filename : foo.txt temp filename : C:\aptana\JaxerDev\tmp\tmp-1 contentType : text/plain size : 816
Well that's really all there is to it. It's simple and easy and you never have to think about anything other than HTML and Javascript.
API docs for the FileInfo object and the Jaxer.Request object are available online.
AjaxWorld, March 18-20, New York, NY
Kevin Hakman presents Aptana Studio: Your Unfair Advantage for AJAX, iPhone, Adobe AIR, PHP and Rails
Development and
Rapid Development of
Enterprise Ajax Apps both on Wednesday, March 19.
iPhone Developer Summit, March 18-20, New York, NY
Also on Wednesday March 19, Kevin Hakman presents Developing AJAX Applications for iPhone and iPod Touch.
EclipseCon, March 17-19, Santa Clara, CA
Eclipse Monkey committer and Aptana engineer Ingo Muschenetz shares
Building Eclipse-based Products: A View From the Trenches
on March 18, and Aptana engineer Kevin Sawicki delivers
Pimp My Editor with insights for extending and customizing features in Eclipse.
I'm happy to announce that RadRails 1.0 has been released today. This release has been a long time coming and includes a lot of new features and polish. We're especially proud of the progress we've made here at Aptana since we took over the project. RadRails 0.7.2 users will definitely want to check out this new release - it offers a more stable environment, full Rails 2.0 support, support for JRuby, and a boatload of new features. For those who want the comprehensive list of changes since the 0.9.3 release, you can find the changelist in ASAP.
The highlights include:
These new features join an already impressive set of functionality:
Please note that unless you've been using 1.0.0 nightlies Aptana/Eclipse will not automatically update you to 1.0. You'll need to force an install of RadRails 1.0 via the Start Page, Plugins Manager, or Software update mechanism that you used to initially install RadRails. For those who prefer to use the Software Update route, the update site URL for RadRails is: http://update.aptana.com/update/rails/3.2/
This week, the Aptana development team continued working on the 1.1.5 release for Aptana Studio and the 0.95 release for the Jaxer server.
New Release
We're planning to release "nightly" versions of Aptana Studio 1.1.5 and Jaxer 0.95 next week. These releases will contain numerous bug fixes. The Aptana Studio release should contain updates for many of the bundled Ajax Library frameworks, including support for EXT 2.0.2., Yahoo UI 2.5, Adobe Spry 1.6, and more.
Tips and Tricks
Do you have a question about an Aptana Studio Pro license? Or do you need some basic troubleshooting help? Visit our recently re-organized Aptana Studio FAQ and see if your question has already been answered there.
If you still need help, you can always file a support request in our ASAP system, of course.
Community Buzz
We'd like to thank our community for their help with submitting bugs and feature requests in ASAP. If you've submitted a bug or a feature request and are curious if we've implemented the fix or feature yet, visit your ASAP ticket and look for the Fix Version field. This field lists the current target release date for the fix or feature.
This past week we released another point release of Jaxer, version 0.9.3, updating the standalone server as well as the one packaged within Aptana Studio. Of course there were bug fixes, performance improvements, and API enhancements. Perhaps most important, this was our first release to officially support Linux. Supporting Linux isn't trivial because of the multitude of variants, but it is very strategic as the deployment platform of choice for many people. Look for more distros being supported and more forms of distribution, from buildable source drops to tarballs and installable packages and even to complete EC2 and VMWare images. And thanks to the community for already helping us with supporting Linux distros.
So where are these releases leading — what are some things on the immediate roadmap for Jaxer?
Oh, and the time frame? We're not exactly the patient type, so for many of these think weeks rather than months. Want something specific to come out even faster? Join the discussions on the forums, join the effort (some folks are supporting Linux distros, others are building persistence frameworks, some are putting together samples), or join our team.