edev
Coding For E2: A Primer (thing)2007-12-04 19:38:56 linked by Oolong Hi, I'm kthejoker. You may know me from such E2 coding projects as the Wheel of Surprise, My Achievements, and that thing that's horrible and needs to be undone or the site will collapse any day now. You know the one. I'm here today to help you learn the basics of what it takes to code for E2, and some of the basic tips and techniques to make your transition to E2 coder a smooth one. To help us out, we're going to be using the Epicenter nodelet as our chief document and reference guide. If I start talking about "the code", that's what I'm referring to. The Basics: PerlBefore we get started diving into the code of Everything2, let's be clear: if you want to code in Everything2, you have to know some Perl. There are a lot of books and websites on Perl and its labyrinthine syntax and methods, but we're just going to cover the nitty gritty here. Basically, you need to know 4 things: variables, operators, functions, and loops. Variables The first thing you need to know about Perl variables in E2 is that we use strict mode, which means you must instantiate each variable in your code with the "my" syntax. This keeps everything in scope for the interpreter. We'll see how this used below. There are three basic variable types in Perl: the scalar ($), the array (@), and the hash (%).
Obviously, there's a lot more to all of this, but for now, this'll get you started. When looking through code, identify scalars, arrays, and hashes, and try to determine their purpose. Sometimes their name makes them obvious ($$NODE{title}) - other times, not so much ($isHappyPanda). Operators Lucky you, you've already learned one operator: the =. That, as you may have noticed, is the assignment operator - you use it to set variables to a particular value. There are also three other types of operators: math, concatentation, and comparison.
Again, not comprehensive, but should help you understand what if ($$NODE{title} eq 'Butterfinger McFlurry') means. Functions Functions and subprocedures are great tools in Perl, but here at E2 we don't generally write our own functions - at least not directly (more on htmlcodes later.) The E2 Perl modules come with a bunch of handy subs, though, that get a lot of use, so you should be familiar with the syntax of a function call: functionName(parameter1, parameter2, etc); Not every function has parameters, but if they are required, you'd better have 'em. Also, many functions return a value that can be used in your code. A simple example is my $fearlessLeader = getNodeById(220); getNodeById does exactly what you think it does, and in this case returns Nate to the variable. Then we do something like return $$fearlessLeader{experience}; which will then print the returned value (Nate's XP) to the display. Loops Loops and conditionals are a fact of life in programming, but luckily they're also pretty straightforward to understand. There are three main loops and conditionals in use at E2:
I'm kind of glazing over these, because really reading an example is the best way to understand what's going on, which we'll cover in our next couple of sections. Overview So we've covered some of the basics of Perl. As we're going through code, you may find yourself asking what this or that bit of code is doing. Always try to break it down in terms of the variables, functions, loops, and operators being invoked. E2 isn't exactly a bastion of good documentation, so I often find myself backtracking from some error point until I get to the root variable or function that is really at issue. Being able to go from the big picture to the small detail is essential to understanding E2 code. Next we'll talk about some of the basic syntax for E2-specific coding: the global variables, database calls, and htmlcode functions. E2 Community Development Newsletter, Summer 20072007-07-22 20:51:59 linked by RoguePoet As many of you may have read, heard, and discussed, there are a number of changes and new developments in the works for Everything2. I had an opportunity recently to meet with Jack, clampe, and many of the staff in person and online, and discussed these developments for our community and our site. We've made good progress over the past many months addressing the implementation, scalability, legal, and staffing concerns. We believe we can make these things happen over the next few months with our coder staff. The new hardware is on its way, and with our newfound help, these features should be implemented by mid-October, 2007. Administrative changesOwnership disclosure: So we're all on the same page, Everything2 is fully owned by Blockstackers Intergalactic, which consists of Nathan Oostendorp, Jeff Bates, Kurt DeMaagd, and Rob Malda. Our hosting provider is Michigan State University's College of Communication Arts and Science, which is coordinated by Cliff Lampe. Katherine Doubek directs the day-to-day operations, overall vision, and administrative staff of Everything2. Jack Thompson is the Editor-in-Chief, in charge of the Content Editors, and all editorial decisions. Copyright of submissions: Our policy isn't changing: users who submit content to the site retain full copyright to that material. We will, however, be branching out our options to make certain open licenses available, such as Creative Commons and Public Domain. These will be configurable when submitting new writeups or editing current ones, and a facility will exist to re-license your writeups en-masse. Behavioral standards: We're in the process of drafting behavioral standards for users and staff. We're not trying to codify common sense, but we feel we need more than our current two words to relay the behavior we expect of ourselves as users, editors, and administrators. Please send any input on these to me. Donation box: Because of our generous hosting contract with MSU, we're going to be closing down the donation box. The money given to it has been used to buy new hardware, or more frequently upgrade existing hardware. With our MSU budget for hardware, we need to avoid conflict of interest and stop taking donations. Thank you for the financial support you've given us over the past many years - it helped keep the servers online and ticking. Staff interaction: We may be allowing noders with symbols to hide them in the Other Users nodelet, and adding a link to a general contact and help page, listing which members of staff are online, and who to contact with various topical, technical, and editorial questions. Likewise, we're also looking at giving the code gods their own usergroup separate from the main pantheon. Relationships with other sites: We've historically been an isolated site, and we're looking to change that. Many of the new features in the works integrate with social bookmarking, networking, and multimedia sites such as flickr, del.icio.us, Digg, reddit, and Facebook. We're also improving our capabilities for linking to content on other sites. New servers: We're pulling in some new hardware, care of the MSU College of Communication Arts and Sciences. We all saw a boost in speed and stability with the current crop of servers, which will improve many times over with the next group. Keeping our current farm around as backup support, we're ordering a rack of hardware to allow us to plan, develop, and deploy updates to the site in an orderly and tested fashion, with minimum downtime. Community2 and "The New E2": Community2 was a testing ground for features we wanted to see on Everything2, as well as a place to explore new ways for noders to contribute to the nodegel. "The New E2" was a group of features we looked at to steer us towards a print journal. Community2 is now offline, and many of its features are in place here, many more on their way. Some features of "The New E2" are still in the works, but with substantial changes. These features are discussed below. Code controlWe're changing the way we look at source control and collaboration here. By the end of this month, or as soon as the development hardware is ready to go, we're going to call a code freeze on developments to the production codebase of Everything2. One of the new servers coming in will be used as a developmental mirror to facilitate orderly planning, development, documentation, and testing of the new codebase before deploying the featureset to the production hardware. This server will be open to our coder staff, edev, and to a group of beta testers. New FeaturesMany of these features have been in the works for years, and are coming to be implemented soon. To be certain, this isn't a list of "what will happen" - it's a discussion of the goals towards which we're working on the back-end. Many of these will come to pass, some will wait until the next development cycle. It will all depend on how much code, documentation, and testing help we get. Usergroups: We'd like to begin allowing the option of open usergroups, allowing users to join and leave without having to contact an owner. Likewise, those groups which prefer to remain controlled should be able to send invitations for users to join. Finally, noders level six and above should be able to create their own groups. User control of their own content: Noders will soon be able to remove their own writeups from the database, and move their writeups to new nodeshells. This frees our editorial and administrative staff to concentrate on improving writeups, rather than filling nuke requests and title changes. Nuke and title change requests will still be around, though, for requests on others' work. A new facility should be created for our staff to review changes to writeups, and for users to flag writeup changes as "significant", or to be reviewed. New themes: We're finishing our XHTML and CSS-driven "Zen" theme, which will allow us to modernize the look and feel of the site. We're planning a contest, with a cash reward for the best new theme for the public face of Everything2. This will also allow us to modernize our printing capabilities, and increase interoperability with mobile users and those who rely on screen readers. Details on that will be posted as soon as the contest rules and XHTML semantic backplane of the site are ready to distribute. Multimedia writeups: We will finally be allowing multimedia content on Everything2. This will include images, audio, and video, with creation tied to the voting / experience system. Images and video will work somewhat analogously, in that they will be integrated into writeups. The way it will work is this: A superdoc will be available to upload images (hosted locally) or YouTube links. Once the content is received, you'll be given a token such as <e2image id="527387610"> to drop into the texts of your writeups. This will integrate the content where you placed the token without having image and video content as standalone nodes. There will be image and video repositories, though, to find images which others have uploaded which you'd want to include in your own writeups. Audio will be managed slightly differently - it'll be integrated with writeups. When posting a writeup, you'll be able to submit an MP3 with that writeup of supporting audio. This is geared toards being a spoken word rendition of the writeup: an audio nodetype.
The heart of Everything2 has always been writing and community, and shall always be writing and community. Images, audio, and video are the spice, not the meat. Multimedia content, at least in the beginning, will only be allowed in writeups, with the possible exception of images in comments. Registries: GTKY content should soon have a home again on Everything2, by means of registries. Taken from Community2, these consist of a question and a series of answers given by users, with the option of displaying the answers on their homenode. The creation of registries will be available begininning with level four. Responses will be votable, but not C!-able, and able to be moderated by our editorial staff in the same manner as writeups. 2 XP will be given for each registry response, with our editorial staff still maintaining oversight. Syndication: Nate has our RSS and ATOM feeds mostly sorted out, and we'll be adding more feeds as time permits. We'll also be standardizing our feed links and header data to allow cleaner interoperability with current standards and neighbor communities. Data from all feeds will be available in RSS, ATOM, and JavaScript feedrolls to be placed on other community sites. We're also working on a module for integration into Facebook's new plugin system. Writeup tagging and searching: We plan on doing away with the "person", "place", "idea", and "thing" designations, in favor of tagging of writeups. This will also facilitate searching the content by metadata while we keep working on how to implement a full-text search as part of a later release. Users will be able to free-text tag their own writeups, and the writeups of others, and will be given 1 XP for doing so. Our editorial staff will be able to moderate submitted tags, and users will be able to tag their own writeups en-masse, in the same manner as assigning their writeups a license. Writeup comments: We're implementing a system of threaded discussion on writeups which will enable users to contribute comments on a piece of writing without having to send a message. Comments will also be votable, but not C!-able. These will be moderated by the userbase on the whole, by means of "spam", "abuse", and "correction / corrected" button in the comment header. These buttons will enqueue the comment to a list to be presented to the editorial staff for review. Noders level three and above will be able to leave comments on writeups. Other writeup features: Once a noder has reached level eight, he or she will be able to create writeups immune to votes and C!s if they so choose. This will be on a writeup-by-writeup basis. We will also begin allowing more than one writeup per user per node, for noders of any level who have as much to say about the city in Texas as the city in France. Writeups should also be able to connect in a series, with "next" and "previous" links in the footer. Finally, writeups will be able to carry their own lede / summary / abstract as a separate text block for quick review through integration into user and site search. Fully semantic URLs: We're working on updating the URL structure of the site to reflect semantic web conventions. URLs such as http://www.everything2.com/index.pl?node_id=650043 , we'll soon be replaced by their semantic equivalents, http://www.everything2.com/users/katherine . This allows the site, in combination with RDF metadata, to be shared wth people as easily as with machines. Frontpage updates: We'd like to completely overhaul the front page, allowing users to see only the information they want, with dynamically controllable and orderable AJAX widgets. The widgets we'd like to implement first are:
The frontpage as shown to users not logged in will be vastly simplified, with only news, recent nodes, C!s, a search box, and editor cools. Social Network: We're adding the facility to link users by XFN relationship types, including friend, colleague, neighbor, and spouse. A full list of these relationship types is available at http://gmpg.org/xfn/11 . This may have an opt-out button for those who'd rather not participate. This data allows us to show users new content contributed by their friends, whether via daylog post aggregation, syndication feeds, or the nightly email. Polls: Polls will now have the option to be available to level one users, and closed polls will show the results regardless of whether you've voted on it. Nightly Email: Finally, we'll be bringing back the E2 Nightly Email. This will allow you to follow the nodes of those in your friends list, and optionaly a summary of all new writeups for the day. There are a number of other site facilities we're looking at streamlining, such as Node Heaven, the Everything FAQ, Message Inbox, and Everything User Search. If you have any suggestions of minor features which can quickly (by your estimate) be added to the code-gel, drop me and message and we'll discuss it. Ad CampaignCoinciding with the above updates, Jack will be running a grassroots international advertising campaign, something in between a flyering effort and a quest. handbills will be made available to participants that they can print and xerox and post on bulletin boards or in coffee houses, record shops, rec rooms, and cafeterias to start. Our target ad-space is anywhere there's foot traffic where potential users could be hanging out or wandering past, the basic idea being to bring us some new talent. Quest participants will be encouraged to daylog their progress and to take pictures of their efforts for XP and C!-type rewards. "How can I help?"If you can volunteer some help, we'd love to speak with you:
-- Katherine
Updates, July 29th, 2007Based on feedback from noders and staff, we've decided to make a few changes to the plan:
edev: Tables and HTML Validation (idea)2003-09-11 23:32:54 Tables and HTML validationHTML in E2 writeups is filtered; only a subset of the available HTML tags are actually allowed. There are approximately two reasons for this:
Tables would be fine if they could be validated to prove that they're well-formed and hence will not break tables outside the writeup. Tables in particular aren't allowed because:
Also, another issue which was not discussed is that allowing tables in writeups might be "exploited" for forcing layout within writeups; eg. to split a writeup into columns, etc. Having written some fairly simple code to validate table HTML, running some performance tests on it seems to show that the 'worst case' HTML (a nightmare of tables, taken from an entire pageload on Community2) indicates that the table validation takes about a fifth of the time the normal HTML validation takes. ApproachThe design of the table validation code emerges from a slightly different approach than is used for general HTML validation. The existing HTML validation code in ecore strips out disallowed tags to create valid HTML. Transforming the markup in such a way can be fairly expensive, and for tables could be quite complex to perform. Hence, a much simpler approach was adopted based on observations of writeup content.
Thus the two cases for which performance should be optimised are the corresponding cases of no table tags at all, and tables which are valid and well-formed. Hence the main code merely scans the structure of the tables in the HTML and determines whether tables have valid structure or not. When a malformed table is discovered, the code adopts an entirely different approach (and one which may in the long run be more useful...) of rendering the table tags visible in the displayed HTML, and adding <div> tags with dashed outlines around the elements to aid debugging. With this approach, the majority of the web server's activity will be in simply checking the validity of any table tags. Here's the source to the htmlcode: # Okay, in brief:
# fast 'cause it's optimised to the 'common' cases:
# Most writeups have no tables. Zoooom!
# Writeups that have tables will mostly have valid tables:
# => Only a quick parse to validate.
# We 'enforce' the validity of tables by outputting debug info
# for badly formed tables. This is UGLY so writeup authors will
# fix 'em quick.
# In an HTMLcode, so compilation of this code is amortised.
# [screenHTML] should still be used, and can be used to control
# attributes in the tags. Ideally this works on the output of
# screenHTML, but only because the 'debug' output uses <div>s
# with dashed outlines to help HTML writers find their oopsies.
# Should be reasonably fast: scans through the HTML using a m''g, which
# is about as fast as anything in perl can be. Stacks the tags (only
# looks at table tags) and checks the structural validity by
# matching a two-level context descriptor (stack . tag) against
# an RE describing valid contexts. (again, perl and RE => faster than
# a bunch of ifs or whatever)
sub tableWellFormed ($) {
my (@stack);
for ($_[0] =~ m{<(/?table|/?tr|/?th|/?td)[\s>]}ig) {
my $tag = lc $_;
my $top = $stack[$#stack];
if (substr($tag, 0, 1) eq '/') {
# Closing tag. Pop from stack and check that they match.
return (0, "$top closed with $tag")
if pop @stack ne substr($tag, 1);
} else {
# Opening tag. Push, and check context is valid.
push @stack, $tag;
return (0, "$tag inside $top")
if (($top.$tag) !~ /^(table(tr)?|tr(td|th)|(td|th)(table))$/);
}
}
return (0, "Unclosed table elements: " . join ", ", @stack)
if ($#stack != -1);
return 1;
}
sub debugTag ($) {
my ($tag) = @_;
my $htmltag = $tag;
$htmltag =~ s/</amp;lt;/g; # should be encodeHTML, but of course
# I don't have that in my standalone testbench.
$htmltag = "<strong><small>amp;lt;" . $htmltag . "amp;gt;</small></strong>";
if (substr($tag, 0, 1) ne '/') {
return $htmltag . "<div style=\"margin-left: 16px; border: dashed 1px grey\">";
} else {
return "</div>". $htmltag;
}
}
sub debugTable ($$) {
my ($error, $html) = @_;
$html =~ s{<((/?)(table|tr|td|th)((\s[^>]*)|))>}{debugTag $1}ige;
return "<p><strong>Table formatting error: $error</strong></p>".$html;
}
my ($text) = @_;
my ($valid, $error) = tableWellFormed($text);
$text = debugTable ($error, $text) if ! $valid;
$text;
A similar approach might yield speed improvements to htmlScreen too. It should be possible, for instance, to construct a single regular expression to determine if some HTML consists entirely of valid tags and attributes (and this regular expression can be constructed automatically, of course). However, since there's a large base of existing writeups that may have invalid tags and attributes that nobody has noticed (since the existing htmlScreen provides no real feedback), it's unlikely that this will be a particularly palatable idea. As a last word, caching of computed results in ecore is something that could be done better, and more consistently; but we all know this by now, and it's late in the evening so I'm not going to tell you things you already know. Y'all can try it out over at http://community2.org?node=test+screenTable or http://kahani.org?node=test+screenTable In particular, I want y'all to try and break it, defeat the validation to get unpleasant HTML through the validator. And remember that in the final version it will be used in conjunction with htmlScreen... ;) edev: escaping brackets in nodes (idea)2003-09-09 14:43:42 Edevdocs are a problem. Firstly, I've seen a lot of edevdocs around that seem to indicate that people aren't aware of the difference between edevdoc's and superdocs. So, you know, maybe we need a bit of documentation. Hey, it's just a thought. Secondly... brackets. Brackets are, of course, a pain on Everythings in general, what with parselinks being used somewhat universally on content. There is no simple, elegant way to denote a bracket that will survive a trip through parselinks. The standard way of passing a bracket through parselinks doesn't pass a bracket through at all; it just passes the HTML entity for a bracket, [. This only happens to look a bit like a bracket when your browser renders HTML. As far as, say, JavaScript is concerned, though, it's not a bracket at all. The 'solution' we currently have in place to this problem, is, in a word, wrong. The solution is that while normal documents are displayed with parselinks, edevdocs are displayed with devparselinks, an entirely different function. This brings trouble when we have a javascript utility, such as E2 Bookmarklets or Writeup table formatting utility which we want to open up to the general E2 user population rather than just edev, the only real way to do this is to convert the edevdoc (viewable only by edev members) into a document, viewable by all. And here we can get bitten by the difference between documents and edevdocs. E2 Bookmarklets uses its own scheme to get round the lack of brackets; if it had used the edevdoc scheme, it would be useless in a document. There are ways to get round the lack of brackets, of course.
However, I would like to propose that we actually solve this problem, rather than simply bubble-pushing it. I see two solutions:
edev: Collapsible Nodelets (idea)2003-04-08 02:34:29 You may remember that, several months ago, we (edev) had a discussion regarding collapsible nodelets. A collapsible nodelet is a regular nodelet with a button that allows you to hide or display the nodelet contents. See a working example here. Collapsible nodelets would allow quick access to the nodelets you want, while keep your screen somewhat clean by giving you the ability to quickly hide or show the ones you refer to semi-frequently (without needing to go through User Settings). If I recall correctly, most everyone liked the idea of collapsible nodelets, but there seemed to be no way to store info regarding which nodelets are collapsed without posting back to the server (not very fast at all). Since no solution appeared to this problem, the idea was pretty much abandoned. Today, however, it suddenly struck me to (duh!) use JavaScript to store data in cookies regarding which nodelets should be collapsed and which should not. I've got a working example running here.
|
Venerable members of this group:
katherine@, jaybonci@, nate@, N-Wing@, 7Ghent, mcSey, pealco, booyaa, yerricde, gnarl, Tristan, bol, jobby, Teiresias, bacchusrx, Chris-O, edev Bot, mouse, Orange Julius, getha, Lila, rdude, bis, Error404, Delta-Sys, call, ascorbic@, Oolong@, Vice_hkpnx, mcai7et2, gate, ReiToei, neil, CloudStrife, drinkypoo, 409, frost, in10se@, gounthar, elem_125, da-x, Devon, 00100, dafydd, opteek, Shatner's Bassoon, kozmund, salome, Two Sheds@, murphy, Anml4ixoye, Hexter, Empiric, TenMinJoe$, Siobhan, electricsheep, Droidkevin5, skongshoj, nosce, weivrorrim, QuantumBeep, OldMiner, telbij, kthejoker, enth, Matthew, Swap, Major General Panic, The Lush, timgoh0, Ulrich, jclast, themanwho, craze, Sir Norris, eien_meru$, Eidolos, rootbeer277@, BlackPawn, Johnny, avalyn@, RoguePoet@, Simulacron3, redbaker, Redalien, maxClimb, Jack@, randrews, Apollyon, jdporter, DTal, vstarre, Allsorts, Ootest, Allsorts, DonJaime, resiak, Senso, Excalibur, resiak, Gryffon, ushdfgakjasgh, Apatrix@, sam512
This group of 104 members is led by katherine@