<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>newLISP on Rockets</title>
  <link>http://newlisponrockets.com</link>
  <description>The newLISP on Rockets blog</description>
  <atom:link href="http://newlisponrockets.com/blog-feed.xml" rel="self" type="application/rss+xml" />
  <pubDate>Wed, 28 Feb 2024 03:26:59 +0000</pubDate>
  <item>
    <title>Rockets 3.0 - an experiment</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=135</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=135</guid>
    <pubDate>Wed, 28 Feb 2024 00:36:29 +0000</pubDate>
    <description> <![CDATA[ Hello Rockets fans!<BR><BR>I&apos;m currently experimenting with HTML5 Canvas, powered by Rockets. It&apos;s in the very early stages right now, but you can see it here:<BR><BR> <a href='https://newlisponrockets.com/rockets-experimental.lsp' target='new'>https://newlisponrockets.com/rockets-experimental.lsp</a><BR><BR>Stay tuned!<BR><BR><img src='images/16pxdither.png'> &lt;- this is a new background image I&apos;m trying out<BR><BR><img src='images/16pxdither2.png'> &lt;- this is another one<BR><BR><img src='images/16pxdither3.png'> &lt;- okay last one ]]></description>
  </item>
  <item>
    <title>Ten years of newLISP on Rockets</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=134</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=134</guid>
    <pubDate>Wed, 26 Oct 2022 22:41:12 +0000</pubDate>
    <description> <![CDATA[ I was idly browsing the Rockets code repository on GitHub and saw that some of the files had &quot;10 years ago&quot; as their last modification date.<BR><BR>I realized that the project has now entered its second decade.<BR><BR>On one hand, this is great! Time to celebrate a milestone! Party hats all around! Whoo hoo!!<BR><BR>But on the other hand, it also made me kind of sad. <i>Ten years??</i> How did time go by that fast? And with that amount of time, how come Rockets isn&apos;t way farther ahead than it is?<BR><BR>Most of the key development work on Rockets was done in the first year of its creation, with brief bursts of activity in 2019 and 2021 as I got Release 2.0 ready to go. <BR><BR>Over the years, I&apos;ve used Rockets in many places. I&apos;ve launched applications internally at work (coincidentally, next year will be my 10th anniversary at my current job) and I&apos;ve launched multiple public websites (including my personal website). Rockets has never failed me. It&apos;s fast, it works, and I can always understand it. Even a decade later, the code is simple and it makes sense.<BR><BR>But public interest in the framework has quietened down since those early days. It makes sense -- when I haven&apos;t spent much time on it, other folks haven&apos;t noticed it much. And that&apos;s been a lot of the time. In addition, interest in blogs and other websites that aren&apos;t social media has also dwindled in the last ten years. That&apos;s a story for another time.<BR><BR>However, I&apos;m not abandoning the project. I have some crazy ideas for web applications that I want to create in the future, and they are going to be powered by Rockets. <BR><BR>No matter what happens in the outside world, Rockets is something I want to always have in my back pocket. It&apos;s mine, and it will always be mine. And it&apos;s also yours -- lots of folks have forked the product, and it will always remain open source.<BR><BR>Here&apos;s to another ten years! ]]></description>
  </item>
  <item>
    <title>Fixing little bugs</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=133</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=133</guid>
    <pubDate>Mon, 16 May 2022 21:38:28 +0000</pubDate>
    <description> <![CDATA[ After a big release like Rockets 2.0, the remaining work is less glamorous, but in many ways more important.<BR><BR>I&apos;ve been keeping track of small issues and bugs here and working my way through fixing all of them: <a href='https://github.com/newlisponrockets/newLISP-on-Rockets/issues' target='new'>https://github.com/newlisponrockets/newLISP-on-Rockets/issues</a><BR><BR>For example, for a long time the &quot;Delete post&quot; button was kind of scary, because it would instantly delete a post with no recourse. And because Rockets was so fast, you couldn&apos;t even hope to interrupt the process! It was like, click, boom, done.<BR><BR>Now I&apos;ve added a secondary confirmation prompt, so you&apos;ll never delete a post by accident.<BR><BR>It&apos;s a small thing, a minor update, but you keep doing these and they start to add up. Things just get a little bit cleaner and nicer.<BR><BR>Feel free to add your own bugs and issue to the list!  ]]></description>
  </item>
  <item>
    <title>Rockets 2.0 is released</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=132</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=132</guid>
    <pubDate>Wed, 23 Feb 2022 22:38:39 +0000</pubDate>
    <description> <![CDATA[ This is the long-awaited 2.0 release of newLISP on Rockets.<BR><BR>It includes new features such as the Admin page, RSS feed, tagging, polls, and others.<BR><BR>It&apos;s suitable for a personal blog and for experimentation in creating new websites.<BR><BR>It comes with a nearly-complete set of user documentation which you can view here: <a href='http://newlisponrockets.github.io/newLISP-on-Rockets' target='new'>http://newlisponrockets.github.io/newLISP-on-Rockets</a>/<BR><BR>There are still some minor known bugs which will be fixed in the upcoming 2.1 release. The 2.1 release will also feature a fully complete set of documentation pages.<BR><BR>This was a self-imposed deadline for me, and I missed my first deadline and had to extend it for a month. Still, I&apos;m proud of what I&apos;ve managed to complete, and I&apos;m looking forward to release 2.1 and 3.0 and beyond! ]]></description>
  </item>
  <item>
    <title>RSS feature is ready!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=131</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=131</guid>
    <pubDate>Thu, 17 Feb 2022 22:14:46 +0000</pubDate>
    <description> <![CDATA[ RSS stands for Really Simple Syndication, and it&apos;s a great way to catch up on all your favorite websites at once, especially those that don&apos;t update that often.<BR><BR>I use newsblur.com, but there are many others, like Feedly, etc. <BR><BR>You can add a feed to a newsreader site (like newsblur) by copying the link on the little orange RSS icon that&apos;s now at the top of the blog.<BR><BR>Happy RSSing!<BR><BR>EDIT: The RSS feature now adds full HTML to each post in the feed, so it can be viewed in all its glory with RSS readers such as NewsBlur. ]]></description>
  </item>
  <item>
    <title>Compiling newlisp from source on CentOS 6.5</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=110</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=110</guid>
    <pubDate>Thu, 22 Jul 2021 18:40:30 +0000</pubDate>
    <description> <![CDATA[ Pre-compiled binaries for newlisp are available for Ubuntu and Debian, but getting a RPM for CentOS is a bit harder.  Another option is to compile from source, which is always fun.  I tried this recently on CentOS 6.5.<BR><BR>First, get the source.  Go to newlisp.org and go to the Downloads page.  You will find something that looks like &quot;download from newlisp.org: newLISP v.10.6.0 source&quot;.  Right click on that link and copy the URL to the clipboard.<BR><BR>Then, from an SSH shell, type <BR><BR><code>wget (right click to paste the link here)</code><BR><BR>This will download the source code in tgz format.  Unzip it by typing:<BR><BR><code>tar zxvf newlisp-10.6.0.tgz</code><BR><BR>Then cd to the new directory.  This is where you&apos;ll compile and build the source code.<BR><BR>First, however, you will need some essential libraries, and you&apos;ll have to add some links so that the makefile knows where to find them.<BR><BR><pre>sudo yum install libffi-devel<BR>sudo yum install readline-devel<BR>cd /usr/include<BR>sudo ln -s /usr/lib64/libffi-3.0.5/include/ffi.h<BR>sudo ln -s /usr/lib64/libffi-3.0.5/include/ffitarget.h</pre><BR><BR>You should have all the dependencies you need, so time to compile!<BR><BR><pre>sudo ./configure<BR>sudo make<BR>sudo make test<BR>sudo make install<BR></pre><BR><BR>You can now run newlisp by typing &quot;newlisp&quot; at the command line.  But first, let&apos;s fix a few modules in preparation for installing Rockets:<BR><BR><pre>Edit file: /usr/share/newlisp/modules/sqlite3.lsp<BR><BR>(set &apos;files (list<BR>    &quot;/usr/lib64/libsqlite3.so.0.8.6&quot; ; CentOS --- add this<BR>    &quot;/usr/lib/libsqlite3.so&quot; ; SuSE Linux<BR>    &quot;/usr/local/lib/libsqlite3.so&quot; ; Linux, BSD, Solaris<BR>    &quot;/usr/pkg/lib/libsqlite3.so&quot; ; NetBSD<BR>    &quot;/usr/local/lib/libsqlite3.so.13.3&quot; ; OpenBSD 4.6<BR>    &quot;/usr/lib/libsqlite3.0.dylib&quot; ; Mac OSX Darwin<BR>    (string (env &quot;PROGRAMFILES&quot;) &quot;/sqlite3/sqlite3.dll&quot;) ; Win32/MinGW<BR>))<BR><BR>Edit file: /usr/share/newlisp/modules/crypto.lsp<BR><BR>(set &apos;files &apos;(<BR>              &quot;C:/Program Files/gnuwin32/bin/libeay32.dll&quot; ; XP<BR>              &quot;C:/Program Files (x86)/gnuwin32/bin/libeay32.dll&quot; ; 7<BR>              &quot;/usr/lib64/libcrypto.so.10&quot; ; CentOS --- add this<BR>              &quot;/usr/lib/x86_64-linux-gnu/libcrypto.so&quot; ; Ubuntu 12.04 LTS<BR>              &quot;/usr/lib/i386-linux-gnu/libcrypto.so&quot;; Ubuntu 12.04<BR>              &quot;/lib/i386-linux-gnu/libcrypto.so.1.0.0&quot; ; UBUNTU Linux 13.04<BR>              &quot;/usr/lib64/libcrypto.so&quot; ; Fedora, CentOS 6.x<BR>              &quot;/usr/lib/libcrypto.so&quot;<BR>              &quot;/usr/lib/libcrypto.so.4&quot;<BR>              &quot;/usr/lib/libcrypto.so.18.0&quot; ; OpenBSD 4.6<BR>              &quot;/usr/lib/libcrypto.so.19.0&quot; ; OpenBSD 5.0<BR>              &quot;/usr/lib/libcrypto.dylib&quot;<BR>              ))<BR></pre><BR><BR>You can see above that we&apos;ve added a couple of lines to these files.  Use your favorite text editor (I used nano in this case)<BR><BR>And that&apos;s it!  You now have a freshly installed build of newlisp, ready to go on your CentOS 6.5 system. ]]></description>
  </item>
  <item>
    <title>Happy New Year, and the future of Rockets</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=130</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=130</guid>
    <pubDate>Thu, 01 Jul 2021 21:10:34 +0000</pubDate>
    <description> <![CDATA[ First off, let me apologize for not posting anything for so long. While I have been occasionally pushing minor bugfixes to the Rockets GitHub repository this year, I haven&apos;t bothered to update this blog for over a year. <BR><BR>Mostly that&apos;s because I&apos;ve been really busy. Work has taken up a lot of my time this year. But that&apos;s no excuse for not popping in and saying &quot;hello&quot; once in a while, even if there is no progress to report.<BR><BR>Also, and let&apos;s face it, 2020 has been a terrible year for everyone. So if there was ever a year to just throw away and not think about any more, 2020 was it.<BR><BR>Anyway, here&apos;s where we are regarding the Rockets 2.0 release and beyond.  <BR><BR>- I want to fix a few more minor bugs, and add the RSS feed feature and a change password feature. But there are no more features to add for the release.<BR><BR>- Once this is done, I want to start working on a comprehensive documentation set for Rockets. I&apos;ve started this here, but it&apos;s just a template so far: <a href='http://newlisponrockets.github.io/newLISP-on-Rockets' target='new'>http://newlisponrockets.github.io/newLISP-on-Rockets</a>/<BR><BR>- I want the doc set to be an in-depth look at the framework, not just to make it easier for folks to understand, but to help myself understand it better in the future.<BR><BR>- The 2.0 release won&apos;t require the doc set to be finished, but I want it to be reasonably well-populated.<BR><BR>- Part of the docs will also include super-simple setup instructions for putting a Rockets installation on Linode, which is a great cloud service that&apos;s cheaper than AWS and offers a starting server at $5 per month, making Rockets affordable by anyone.<BR><BR>- My timeline for this release is July 1, 2021. If it&apos;s finished earlier, great! But that&apos;s the final date for the release. <i>EDIT: Due to real-world events (like the recent heatwave) I&apos;m bumping this release date forward, to July 31, 2021. Sorry for the delay!</i><BR><BR>I also want to let you know that I&quot;m already thinking about Rockets 3.0. I have some really interesting ideas and plans for making Rockets a kind of &quot;virtual space&quot; for people to hang out in, something that you can customize to your own aesthetic tastes and make it a hub for you and your friends to hang out. I know that Facebook and Twitter have taken over this space, but I have ideas for a kind of counter to this, a very personal thing that anyone can run and have complete control over their own data.<BR><BR>Anyway, that&apos;s all, and I hope everyone has an amazing 2021!  ]]></description>
  </item>
  <item>
    <title>newLISP on Rockets now on HTTPS!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=129</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=129</guid>
    <pubDate>Wed, 30 Oct 2019 18:32:12 +0000</pubDate>
    <description> <![CDATA[ You&apos;ll notice a neat little lock icon in the upper left of the URL bar, courtesy of Let&apos;s Encrypt, a non-profit organization that hands out SSL certificates for websites. You just have to install open-source software on the server, which proves you are the owner of a website, and you can automatically get a certificate.<BR><BR>I have been putting off installing it for a long time, because I was worried that it might break something. But it was super quick and easy to set up. Here&apos;s the <a href='https://www.digitalocean.com/community/tutorials/how-to-set-up-let-s-encrypt-certificates-for-multiple-apache-virtual-hosts-on-ubuntu-14-04'>guide</a> I used (for Ubuntu 14, but worked on 18 just as well):<BR><BR>Yay encryption! ]]></description>
  </item>
  <item>
    <title>New! Simple one-button installer for Rockets on Ubuntu 14 LTS</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=112</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=112</guid>
    <pubDate>Wed, 19 Jun 2019 22:49:45 +0000</pubDate>
    <description> <![CDATA[ It&apos;s been a while since I&apos;ve updated this site, but it&apos;s not because I haven&apos;t been working on Rockets!  In fact, I&apos;ve been using and improving it at my job, and I&apos;m doing work for not only the 1.0 release but some design work for what I want to see in Rockets 2.0!<BR><BR>In the mean time, I&apos;ve made a new script that will do all the installation and configuring for Rockets on a bare-bones Ubuntu 14 LTS server <i>(NOTE:The script has also been tested and adapted so it will work on Ubuntu 16 and 18).</i>  All you have to do is install the OpenSSH server when you&apos;re creating your server, then log in via SSH, type<BR><BR><pre>wget <a href='http://newlisponrockets.com/downloads/install_rockets.sh' target='new'>http://newlisponrockets.com/downloads/install_rockets.sh</a><BR></pre><BR><BR>Then make the script executable:<BR><BR><pre>sudo chmod +x install_rockets.sh<BR></pre><BR><BR>And then run the script:<BR><BR><pre>sudo ./install_rockets.sh<BR></pre><BR><BR>And that&apos;s it!  It takes care of all the fiddly bits (downloading newlisp, downloading Rockets, getting Bootstrap and the libraries and images, fixing the crypto library, setting permissions, etc) and leaves you with a fully-working Rockets system.<BR><BR>Enjoy! ]]></description>
  </item>
  <item>
    <title>newLISP on Rockets is on a new server!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=128</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=128</guid>
    <pubDate>Wed, 05 Jun 2019 21:30:54 +0000</pubDate>
    <description> <![CDATA[ Well, I&apos;ve finally done it, I&apos;ve pulled the trigger and switched the DNS for newlisponrockets.com from the old server to the new one. <BR><BR>Everything should work the same, only the new server is a lot faster.<BR><BR>I set up the old server in 2013. It was a t1.micro instance on AWS, which is no longer supported by Amazon. The new server is a t3.nano, which is cheaper yet faster. Ah, technology!<BR><BR>Please let me know if you have any problems with the new site.<BR><BR>EDIT: One thing that is different with the t3.nano is that it has slightly less RAM than the t1.micro instance. I also run a MySQL server on this box and I may need to play with some settings. So if you see an &quot;out of memory&quot; message this is what has happened.<BR><BR>Why use such a small server? It&apos;s a good way to test how well Rockets runs given hardware constraints. In the future I might upgrade to something beefier. It&apos;s also a way to show off the power of Rockets! For example, this page rendered in 6 milliseconds. That&apos;s pretty impressive! ]]></description>
  </item>
  <item>
    <title>Rough schedule for completion of Rockets 2.0</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=126</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=126</guid>
    <pubDate>Thu, 04 Apr 2019 10:20:39 +0000</pubDate>
    <description> <![CDATA[ This is just a rough list of the remaining tasks that I need to finish in order to get Rockets 2.0 out the door:<BR><BR>- Migrate last author and last post date with script DONE<BR>- Update posting page to update last author and last post date, sort forums by last post date DONE<BR>- Editing of posts and comments after posting (admins only?) DONE<BR>- Create post link for admins on front page DONE<BR>- Comics support (as on my home page) DONE<BR>- Podcast support (as on my home page) -- Basically done, barring some minor tweaks  --<BR>- RSS support<BR>- Font changes / color changes in CSS in Admin panel (would be neat to have different colors for each tab like Writing Holmes)<BR>- Multiple site support (via Apache)<BR>- set Apache permissions on .lisp and .db files<BR>- testing installation script on bare Linux VM<BR><BR>Some of these will take more time than others, but I&apos;ll revisit this thread from time to time to update my progress. ]]></description>
  </item>
  <item>
    <title>This is a test post to test tags</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=125</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=125</guid>
    <pubDate>Tue, 26 Mar 2019 13:35:27 +0000</pubDate>
    <description> <![CDATA[ This is a test post to test tags. I&apos;ve added the &quot;Test&quot; to this post.<BR><BR>EDIT: Now testing image uploading<BR><BR><img src='images/sun_halloween.jpg'> ]]></description>
  </item>
  <item>
    <title>Newlisp on Rockets returns with a new mission</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=123</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=123</guid>
    <pubDate>Fri, 07 Sep 2018 14:49:59 +0000</pubDate>
    <description> <![CDATA[  When I started to write Rockets, I had a crazy dream. Then the dream came true, and I didn&apos;t know what to do.<BR><BR>The dream of newLISP on Rockets was to produce something unique and interesting, and share it with the world. I wanted to show that you could make a lightweight web framework that could make functional and fast websites with a minimal amount of code. And I wanted to do it with LISP, because I had fallen in love with that language.<BR><BR>I had some experience making websites with the Dragonfly framework, including my own personal site. That framework wasn&apos;t being updated any more, though, as the author had moved on to other things. So using Dragonfly as a starting point, I wrote my own framework. It was an intellectual exercise for me, and when it was finished I didn&apos;t have much else I wanted to do with it. It was out in the world, and other people could use it for free and add to it or extend it as they wished.<BR><BR>That was five years ago.<BR><BR>Since then, I got a new job where I used Rockets to launch one major internal tool, and prototype others. But the company I worked for was all-in on Python, and so I was strongly encouraged to learn and use that language. There&apos;s nothing wrong with Python-- it&apos;s a clean and flexible all-purpose language with strong library support and a large community. There is a lot of comfort and safety in Python. <BR><BR>In that time, I&apos;ve read essay after essay from people who once used LISP to do amazing things and who have all moved on. Paul Graham, after failing to convert the world to his own new Lisp dialect, launched the successful Y Combinator startup incubator. Andy Gavin, who by his own admission was a &quot;diehard LISP advocate&quot; for twenty years, coded Crash Bandicoot and four Jak &amp; Daxter games in his own Game Oriented Object LISP language. Now he codes in Ruby and says that &quot;Libraries and implementation matter a lot. Momentum too.&quot; And the author of the Dragonfly framework, after bemoaning that not enough people picked up his object-oriented framework for newLISP, left the language entirely.<BR><BR>And here I was, coding in Python at work and thinking of LISP fondly, like one does of a first love. The years went by and memories got hazier. Was I just going to be the next person in a long line of coders who abandoned LISP?<BR><BR>Surely all these smart people had a point. Why go it alone with LISP when you can use something popular like Python and enjoy tons of libraries and support? Why struggle with something that&apos;s so different and unpopular and a bit weird? <BR><BR>But then again, why did all these smart people spend so many years (and even decades) doing exactly that?<BR><BR>In my spare time, I am a science fiction author. I have a new book coming out next year and I needed a website to help market it. I thought about setting up a site on Squarespace (yes, I listen to a lot of podcasts!) It&apos;s fast and easy, you can customize it to look like you want and... it would be just like all the other author book websites that nobody reads. I wanted something very different and unique. Something nobody else would have.<BR><BR>And then I thought about Rockets.<BR><BR>Now, I had already partially converted my personal site from Dragonfly to Rockets, but this was just using the new headers and login system, and doing some find-replace on a few functions (you can read about how to do that here: <a href='http://newlisponrockets.com/rockets-item.lsp?p=85' target='new'>http://newlisponrockets.com/rockets-item.lsp?p=85</a>). Much of the site was a bunch of custom code that just worked for my personal site, and wasn&apos;t the same as the site you get from the newLISP on Rockets GitHub repository. So Rockets did some things and my personal blog did some other things, but neither of them did what I wanted from a new website to promote my book. And my personal website was looking a bit old-fashioned anyway, and it was running on an ancient t1.micro instance on AWS that was expensive and barely supported and needed to be moved over to a new instance years ago.<BR><BR>That&apos;s when it hit me. I needed a new version of Rockets. One where I could recreate my personal blog and also have a marketing site for my new book, using the same framework. With a simple Apache configuration, Rockets already supports multiple sites-- I have several different sites running on that one AWS instance (see here for how that works: <a href='http://newlisponrockets.com/rockets-item.lsp?p=99' target='new'>http://newlisponrockets.com/rockets-item.lsp?p=99</a>). But I want a single codebase that can make different-looking sites depending on what you want.<BR><BR>newLISP on Rockets has a few advantages other than uniqueness. It is fast--wickedly fast. And it&apos;s simple-- the whole design principle was to make the simplest possible framework for making dynamic websites. What it&apos;s missing are features. I had thought that other people would take the basic Rockets framework and add their own features, but I think a lot more people would rather have a simple website with all the basic features ready to go.<BR><BR>To get there will take some time and effort on my part. But I have a good motivation to do so-- my own new website-- and I&apos;m writing out a plan for me to get there. I&apos;m going to make a new thread to report on the work being done. At the end, I hope to launch Rockets 2.0-- a basic but full-featured blog, ready to go, out of the box, batteries included. <BR><BR>I&apos;m excited about the journey! ]]></description>
  </item>
  <item>
    <title>Thing-a-day update for newLISP on Rockets 2.0</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=124</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=124</guid>
    <pubDate>Fri, 07 Sep 2018 14:46:15 +0000</pubDate>
    <description> <![CDATA[ <BR> If you haven&apos;t yet, read my previous post here to get the background information: <a href='http://newlisponrockets.com/rockets-item.lsp?p=123' target='new'>http://newlisponrockets.com/rockets-item.lsp?p=123</a><BR><BR>This thread is where I will update all new progress on newLISP on Rockets 2.0. ]]></description>
  </item>
  <item>
    <title>Setting up a new site with newLISP on Rockets!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=99</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=99</guid>
    <pubDate>Fri, 14 Feb 2014 00:27:18 +0000</pubDate>
    <description> <![CDATA[ I&apos;ve been setting up a lot of new sites lately using newLISP on Rockets.  Here&apos;s the process for making a brand new site from scratch.<BR><BR>This assumes you&apos;ve already got Linux and Apache installed on the server.  This is easy to do with Ubuntu Server-- just select &quot;LAMP&quot; at install time.  All these instructions are for Ubuntu but they should work on other Debian-based Linuxes.<BR><BR>Your web directory should be in /var/www.<BR><BR><h4>1. Install newLISP</h4><BR><BR>* Download newLISP Debian package by going to newlisp.org, finding the most recent newLISP .deb package, and typing<BR><code><BR>wget url-of-most-recent-newLISP-package<BR></code><BR><BR>NOTE: This is the 32-bit version of newLISP.  If you want the 64-bit version, you will need to compile it yourself, or get one of the unsupported 64-bit Debian installers (do a Google search for the most recent version).  Also, the version numbers may change in the future-- go to the Downloads page at newlisp.org to get the current version.<BR><BR>Then install it using the following command:<BR><BR><code><BR>sudo dpkg -i newlisp_10.5.4-1_i386.deb<BR></code><BR><BR><h4>2. Install SQLite</h4><BR><BR>SQLite is the database used for all permanent storage in newLISP on Rockets.  To install it, type:<BR><BR><code><BR>sudo apt-get install sqlite3<BR></code><BR><BR><h4>3. (OPTIONAL) Set up a new site in /etc/apache2/sites-available</h4><BR><BR>NOTE: This step is only if you want multiple websites (multiple URLs) on your Ubuntu install.  If you don&apos;t need this, you still have to edit your /etc/apache2/sites-available/default file and add &quot;+ExecCGI&quot; to the Options line under &lt;Directory /var/www/&gt;<BR><BR>Add a new site file, in this case we&apos;re calling it &quot;starscene.net&quot; which is the URL of the new site.  Make it look something like this:<BR><BR><pre><BR>&lt;VirtualHost *:80&gt;<BR>        ServerAdmin starman@starscene.net<BR>        ServerName starscene.net<BR>        ServerAlias www.starscene.net<BR>        DocumentRoot /var/www/starscene<BR>        &lt;Directory /&gt;<BR>                Options FollowSymLinks +ExecCGI<BR>                AllowOverride All<BR>        &lt;/Directory&gt;<BR>        &lt;Directory /var/www/&gt;<BR>                Options Indexes FollowSymLinks MultiViews +ExecCGI<BR>                AllowOverride All<BR>                Order allow,deny<BR>                allow from all<BR>        &lt;/Directory&gt;<BR>&lt;/VirtualHost&gt;<BR></pre><BR><BR><h4>4. (OPTIONAL) Make a new subdirectory in your web root and enable the site, edit permissions</h4><BR><BR>NOTE: Again, this step is only if you are creating multiple sites on your Ubuntu server.  If you have just one site, you can skip this step.<BR><BR>enable site sudo a2ensite sitename.com<BR>cd /var/www<BR>mkdir sitename<BR>sudo chown www-data sitename<BR><BR><h4>5. Get newLISP on Rockets</h4><BR><BR>cd /var/www/sitename (if you have only one site, type &quot;cd /var/www&quot; instead to go to the root directory of your web server)<BR>sudo wget <a href='https://github.com/newlisponrockets/newLISP-on-Rockets/archive/master.zip' target='new'>https://github.com/newlisponrockets/newLISP-on-Rockets/archive/master.zip</a><BR>sudo unzip master.zip  (if you get a message about unzip not installed, just type &quot;sudo apt-get install unzip&quot; first)<BR>cd newLISP-on-Rockets-master<BR>sudo cp -R * ..<BR><BR><h4>6. Fix the crypto library!</h4><BR><BR>Unfortunately, the library libcrypto.so is always changing version numbers, and newLISP often doesn&apos;t know where to find it.  So you have to find it yourself.<BR><BR>cd /<BR>sudo find . name libcrypto*<BR><BR>You should get something back like &quot;./lib/i386-linux-gnu/libcrypto.so.1.0.0&quot;<BR><BR>Now, you have to tell newLISP where to find this cryptic cryptography file:<BR><BR>cd /usr/share/newlisp/modules<BR>sudo nano crypto.lsp<BR><BR>Page down a couple of times to get to the long list of places to find the library, and add &quot;/lib/i386-linux-gnu/libcrypto.so.1.0.0&quot; or whatever you found from before to the end of this list.<BR><BR>Some day, I&apos;m going to write a script to do this automatically.<BR><BR><h4>7. Run the setup script</h4><BR><BR>cd /var/www (or cd /var/www/sitename if you&apos;ve set up multiple sites)<BR>sudo newlisp setup-rockets.lisp<BR>sudo chown www-data *.db <BR><BR>If it works, it will ask you for some names and email addresses and such, and then spit out a list that is the first entry in the new database for Rockets, ending in &quot;nil nil)&quot;.  Don&apos;t worry about those nils.  They are good nils.<BR><BR><h4>8. Get Bootstrap</h4><BR><BR>NOTE: Rockets uses an older version of Bootstrap. I&apos;m working on updating it to work with the newer version, but for now, use the following tools to grab the CSS<BR><BR>cd /var/www (or cd /var/www/sitename if you&apos;ve set up multiple sites)<BR>sudo mkdir css<BR>cd css<BR>sudo wget <a href='http://newlisponrockets.com/css/bootstrap.css' target='new'>http://newlisponrockets.com/css/bootstrap.css</a><BR>sudo wget <a href='http://newlisponrockets.com/css/bootstrap-responsive.css' target='new'>http://newlisponrockets.com/css/bootstrap-responsive.css</a><BR>sudo wget <a href='http://newlisponrockets.com/css/datepicker.css' target='new'>http://newlisponrockets.com/css/datepicker.css</a><BR>sudo wget <a href='http://newlisponrockets.com/css/docs.css' target='new'>http://newlisponrockets.com/css/docs.css</a><BR>cd ..<BR>sudo mkdir js<BR>cd js<BR>sudo wget <a href='http://newlisponrockets.com/js/jquery-1.8.2.min.js' target='new'>http://newlisponrockets.com/js/jquery-1.8.2.min.js</a><BR>sudo wget <a href='http://newlisponrockets.com/js/bootstrap.min.js' target='new'>http://newlisponrockets.com/js/bootstrap.min.js</a><BR>sudo wget <a href='http://newlisponrockets.com/js/bootstrap-datepicker.js' target='new'>http://newlisponrockets.com/js/bootstrap-datepicker.js</a><BR><BR><h4>9. Get images!</h4><BR><BR>cd /var/www (or cd /var/www/sitename if you&apos;ve set up multiple sites)<BR>sudo mkdir images<BR>cd images<BR>sudo wget <a href='http://newlisponrockets.com/images/poweredby.png' target='new'>http://newlisponrockets.com/images/poweredby.png</a><BR>sudo wget <a href='http://newlisponrockets.com/images/newlisp-rockets-picture.jpg' target='new'>http://newlisponrockets.com/images/newlisp-rockets-picture.jpg</a><BR>sudo wget <a href='http://newlisponrockets.com/images/new-icon.jpg' target='new'>http://newlisponrockets.com/images/new-icon.jpg</a><BR>sudo wget <a href='http://newlisponrockets.com/images/newlisp-rockets-picture-small.jpg' target='new'>http://newlisponrockets.com/images/newlisp-rockets-picture-small.jpg</a><BR>sudo mkdir avatars<BR>cd avatars<BR>sudo wget <a href='http://newlisponrockets.com/images/avatars/unknown.png' target='new'>http://newlisponrockets.com/images/avatars/unknown.png</a><BR><BR>And you should be good to go!  Set your DNS to point to the IP of your web server, and Apache will automatically redirect any links to the site to the sub-directory and run index.cgi, which loads Rockets and redirects to rockets-main.lsp, the main page.<BR><BR><h3>Troubleshooting!!!</h3><BR><BR><h4>I get a &apos;crypto library not found&apos; error!</h4><BR><BR>You have to find the libcrypto library and add it to /usr/share/newlisp/modules.crypto.lsp (See the detailed description above)<BR><BR><h4>Apache just shows the text of the newlisp script, instead of executing it!</h4><BR><BR>You could try adding the line:<BR><BR><code><BR>AddHandler cgi-script .cgi .lsp<BR></code><BR><BR>To /etc/apache2/sites-available/default (or instead of default, your site name)<BR><BR>If things really don&apos;t want to execute, try this:<BR><BR>cd /var/www<BR>sudo nano .htaccess<BR><BR>Add the line &quot;Options +ExecCGI&quot;<BR><BR><h4>It works, but I can&apos;t write to the database (I can&apos;t make any new posts)</h4><BR><BR>Make sure you&apos;ve set the permissions on DATABASENAME.db (whatever name you gave it at the start).  Usually chown www-data *.db works.  You may also have to go to /var and type chown www-data www to give permission to the web server to create new files in that directory.<BR><BR><h4>It works, but the front page still shows the &quot;It works but no content has been added yet&quot; page, I have to go to rockets-main.lsp manually</h4><BR><BR>Sometimes the default index.cgi won&apos;t execute if you have PHP installed, or if you have index.html already in /var/www.  Delete /var/www/index.html and, if necessary, create a new file called index.php that has the following lines:<BR><BR>&lt;?php<BR>echo(&apos;Hello&apos;);<BR>header( &apos;Location: rockets-main.lsp&apos; );<BR>?&gt;<BR><BR>This will redirect the front page of the site to the first page of Rockets.<BR><BR>Any other issues?  Post a reply to this thread and I&apos;ll try to answer them! ]]></description>
  </item>
  <item>
    <title>A new cover page for Rockets!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=101</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=101</guid>
    <pubDate>Tue, 16 Jul 2013 17:22:47 +0000</pubDate>
    <description> <![CDATA[ The little cartoon rocket was cute, but I think it&apos;s time for a more exciting image for the front page.<BR><BR>I modeled and rendered the rocket image in Blender and made the textures in Photoshop.  The background is a photo from NASA. ]]></description>
  </item>
  <item>
    <title>Yet another test poll</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=96</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=96</guid>
    <pubDate>Mon, 25 Mar 2013 16:49:44 +0000</pubDate>
    <description> <![CDATA[ <h4>How many roads must a man walk down?</h4><BR><form name=poll method=POST action=rockets-poll.lsp><BR><input type='radio' name=Yet_another_test_poll value=0 checked=yes> one<BR><input type='radio' name=Yet_another_test_poll value=1> two<BR><input type='radio' name=Yet_another_test_poll value=2> three<BR><input type='radio' name=Yet_another_test_poll value=3> four<BR><input type='radio' name=Yet_another_test_poll value=4> forty-two <br><br><input type=submit value='Vote'></form><BR><BR><BR> This one features some text in here to try and see how that affects the formatting. ]]></description>
  </item>
  <item>
    <title>This is another poll test - 2</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=93</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=93</guid>
    <pubDate>Thu, 21 Mar 2013 13:00:52 +0000</pubDate>
    <description> <![CDATA[ <h4>How many friggles in the flooby?</h4>
<form name=poll method=POST action=rockets-poll.lsp>
<input type='radio' name=This_is_another_poll_test_-_2 value=0> one<BR><input type='radio' name=This_is_another_poll_test_-_2 value=1> two<BR><input type='radio' name=This_is_another_poll_test_-_2 value=2> three<BR><input type='radio' name=This_is_another_poll_test_-_2 value=3> four <br><br><input type=submit value='Vote'></form>


 Testing ]]></description>
  </item>
  <item>
    <title>How do I build a Forgot Password module?  Here&apos;s how!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=88</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=88</guid>
    <pubDate>Wed, 06 Mar 2013 17:18:44 +0000</pubDate>
    <description> <![CDATA[ I&apos;d been putting off doing a Forgot Password module for newLISP on Rockets because it is such a pain doing it properly.  You can&apos;t just have one click to reset a password, because what if someone else knows your user name or email?  Then they could change your password to whatever they want!<BR><BR>So what most sites do is let you trigger a reset, then send a confirmation message to that email address, and then make you retrieve the email and click on a special link to reset your password.<BR><BR>Funnily enough, on another site I&apos;m developing I was testing logging out and logging in, and you know what? I forgot my password.  So I figured this was as good as an excuse as any to build a Forgot Module!  (And no, I couldn&apos;t just grab the password from the database, because it&apos;s encrypted for security!)<BR><BR>I wanted the whole thing to be only a single page for simplicity.  <b>rockets-forgotpassword.lsp</b> is the page that handles triggering the email, confirming and sending the email, and resetting the password, so the code flow may not seem obvious at first glance.  The emails contain links of unique identifiers (sometimes called GUIDs) that expire after an hour and are matched with email addresses of the people who sent them, so people won&apos;t be able to guess them either.  The tokens are stored in a file called <b>reset-tokens.lisp</b>.  This file is automatically generated if it doesn&apos;t previously exist.<BR><BR>One more thing: to get the email links to work, the module needs two additional configuration options in <b>Rockets-config.lisp</b>:<BR><BR><pre><BR>(set &apos;AdminEmail &quot;newlisponrockets@newlisponrockets.com&quot;)<BR><BR>(set &apos;SiteURL &quot;newlisponrockets.com&quot;)<BR></pre><BR><BR>You should change these to your own email and URL from whatever domain you are running Rockets on.<BR><BR>The code, along with the rest of Rockets, is available in GitHub here: <a href='https://github.com/newlisponrockets/newLISP-on-Rockets' target='new'>https://github.com/newlisponrockets/newLISP-on-Rockets</a> ]]></description>
  </item>
  <item>
    <title>How to compile newLISP from source on 64-bit Ubuntu</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=87</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=87</guid>
    <pubDate>Tue, 26 Feb 2013 15:35:09 +0000</pubDate>
    <description> <![CDATA[ I&apos;ve been wanting to update newLISP on my development box to see what neat new changes and features are available.  Unfortunately, it&apos;s a 64-bit Ubuntu install, and pre-packaged binaries are only available for i386 (32-bit) on newlisp.org.  <BR><BR>So what to do?  Well, compile from source of course!  <BR><BR>First get the source:<BR><BR><pre><BR>cd ~<BR>wget <a href='http://www.newlisp.org/downloads/newlisp-10.4.5.tgz' target='new'>http://www.newlisp.org/downloads/newlisp-10.4.5.tgz</a><BR>tar zxvf newlisp-10.4.5.tgz<BR>cd newlisp-10.4.5<BR></pre><BR><BR>Now you&apos;re in the source code directory.  First you need a few libraries, then you can go ahead and compile:<BR><BR><pre><BR>sudo apt-get install libffi-dev<BR>sudo apt-get install libreadline6 libreadline6-dev <BR>sudo make<BR>sudo make install<BR></pre><BR><BR>And that&apos;s it!  To get Rockets to work on Ubuntu, you&apos;ll have to go into the sqlite3.lsp module and add the appropriate path for where it lives on Ubuntu 64-bit:<BR><BR><pre><BR>cd /usr/share/newlisp/modules<BR>sudo nano sqlite3.lsp<BR></pre><BR><BR>Add the following line under the list of similar lines:<BR><BR><code>        &quot;/usr/lib/x86_64-linux-gnu/libsqlite3.so&quot; ; Ubuntu</code><BR><BR>Then do the same for crypto.lsp:<BR><BR><code>      &quot;/usr/lib/x86_64-linux-gnu/libcrypto.so.0.9.8&quot; ; Ubuntu</code><BR><BR>And you&apos;re good to go! ]]></description>
  </item>
  <item>
    <title>Converting other newLISP code to Rockets</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=85</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=85</guid>
    <pubDate>Thu, 21 Feb 2013 18:54:17 +0000</pubDate>
    <description> <![CDATA[ Today I relaunched my personal website at <a href='http://www.jeremyreimer.com' target='new'>http://www.jeremyreimer.com</a>.  It had previously been running on Dragonfly, a web development framework that inspired me to write Rockets.<BR><BR>Converting the code was really easy.  All it took was the following:<BR><BR>1. Replace all instances of (print) with (display) and (println) with (displayln)<BR>2. Remove Dragonfly-specific functions like (web-root) that are no longer necessary.<BR>3. Make sure to start each page with:<BR><BR><pre><BR>#!/usr/bin/env newlisp<BR><BR>(load &quot;newlisp-rockets.lisp&quot;) ; this is where the magic happens!<BR></pre><BR><BR>and end each page with<BR><BR><pre><BR>(display-footer &quot;Jeremy Reimer&quot;)<BR>(display-page)	<BR></pre><BR><BR>And that&apos;s pretty much it!  So if you want to convert any Dragonfly code to Rockets, that&apos;s how you do it. ]]></description>
  </item>
  <item>
    <title>Refactoring Rockets</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=84</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=84</guid>
    <pubDate>Fri, 15 Feb 2013 11:59:24 +0000</pubDate>
    <description> <![CDATA[ I&apos;ve made some changes to the code base that will make it easier to start new custom sites based on Rockets.  This is for my benefit as well as everyone else&apos;s-- I&apos;m currently developing a bunch of new sites with this technology!<BR><BR>Now, when you run <b>setup-rockets.lisp</b>, the script asks you for a long and short name for your blog, an owner name, and the database name.  These are automatically saved in a new configuration file called <b>Rockets-config.lisp</b>.  I went through every page in the Rockets blog and changed it so that it reads various custom data about the blog from the config file.<BR><BR>The config file looks like this:<BR><BR><pre><BR>(context &apos;RocketsConfig)<BR>(set &apos;Database &quot;ROCKETS-BLOG&quot;)<BR>(set &apos;Name &quot;The newLISP on Rockets Blog&quot;)<BR>(set &apos;ShortName &quot;newLISP on Rockets&quot;)<BR>(set &apos;Owner &quot;Rocket Man&quot;)<BR>(context MAIN)<BR></pre><BR><BR>This should make it a lot easier to set up new sites with different configurations. ]]></description>
  </item>
  <item>
    <title>Copying Apache log files to a database</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=79</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=79</guid>
    <pubDate>Fri, 15 Feb 2013 10:57:40 +0000</pubDate>
    <description> <![CDATA[ Apache log files typically just sit around filling up your hard drive space, a vast array of text too unwieldy to search through.<BR><BR>A useful thing to do is to parse these files and copy them to a database.  I&apos;ve written a script that will do this using Rockets.  It&apos;s not a web page-- it&apos;s a script that you should run from the command line (use <b>sudo newlisp log-to-database.lsp</b>)  It will create a new database from scratch called SERVER-LOGS.db that you can then query and search using SQLite.<BR><BR>The script can be found here: <a href='https://github.com/newlisponrockets/newLISP-on-Rockets/blob/master/log-to-database.lsp' target='new'>https://github.com/newlisponrockets/newLISP-on-Rockets/blob/master/log-to-database.lsp</a><BR><BR>Note: I may be updating this later, as the database files seems quite large (only slightly smaller than the logs themselves) ]]></description>
  </item>
  <item>
    <title>Adding custom Javascript or jQuery to your page in Rockets</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=83</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=83</guid>
    <pubDate>Wed, 06 Feb 2013 17:53:38 +0000</pubDate>
    <description> <![CDATA[ newLISP on Rockets comes with and works with jQuery, which lets you do all sorts of wild and wonderful things on your page. But where should you put your Javascript code?<BR><BR>It doesn&apos;t really matter where it goes as long as there are &lt;script&gt; tags around it, but sometimes you want to defer execution to the end of the page. This leads to the best performance, because the user isn&apos;t waiting for the Javascript to load before seeing the page elements.<BR><BR>I&apos;ve modified (display-footer) to let you add a string of Javascript or jQuery code to your page and insert it right at the end. You assign the code to a string variable and then just call (display-footer &quot;Your name&quot; name-of-string-variable) and it will execute the Javascript or jQuery code at the end of the page. ]]></description>
  </item>
  <item>
    <title>Converting JSON data into a list</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=81</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=81</guid>
    <pubDate>Wed, 30 Jan 2013 16:28:47 +0000</pubDate>
    <description> <![CDATA[ JSON stands for the JavaScript Object Notation, and it&apos;s used by lots of applications because it&apos;s much more compact than the bulky XML format.  It&apos;s also suspiciously similar to LISP lists, which isn&apos;t that surprising considering that JavaScript was originally written as a LISP interpreter.<BR><BR>The basic format is something like this:<BR><BR><pre><BR>{<BR>    &quot;firstName&quot;: &quot;John&quot;,<BR>    &quot;lastName&quot;: &quot;Smith&quot;,<BR>    &quot;age&quot;: 25,<BR>    &quot;address&quot;: {<BR>        &quot;streetAddress&quot;: &quot;21 2nd Street&quot;,<BR>        &quot;city&quot;: &quot;New York&quot;,<BR>        &quot;state&quot;: &quot;NY&quot;,<BR>        &quot;postalCode&quot;: 10021<BR>    },<BR>    &quot;phoneNumber&quot;: [<BR>        {<BR>            &quot;type&quot;: &quot;home&quot;,<BR>            &quot;number&quot;: &quot;212 555-1234&quot;<BR>        },<BR>        {<BR>            &quot;type&quot;: &quot;fax&quot;,<BR>            &quot;number&quot;: &quot;646 555-4567&quot;<BR>        }<BR>    ]<BR>}<BR></pre><BR><BR>I&apos;ve written a function in Rockets that converts this notation into a native newLISP list.  Basically all I&apos;ve done is replace { with ( and [ with (, then removed colons, commas, and other extraneous syntax.  I ran into a small problem with very large text strings, because newLISP&apos;s internal list evaluator doesn&apos;t like them and returns a &quot;string token too long&quot; error.  To fix this, I put [text] and [/text] in place of everything that had quotes, which tells newLISP&apos;s internal evaluator to treat it as a long string of text.  Using (read-eval) I convert this long string of long strings back into a list, and all the [text] and [/text] goes away and you have a normal list!<BR><BR>The function is called <b>(convert-json-to-list)</b> and it&apos;s included in Rockets.  I&apos;m already finding it useful for my new project. ]]></description>
  </item>
  <item>
    <title>How to extract data from an RSS feed in Rockets</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=80</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=80</guid>
    <pubDate>Fri, 25 Jan 2013 14:12:04 +0000</pubDate>
    <description> <![CDATA[ RSS feeds are useful and great, but the XML structure they come in is rather unwieldy to read through and parse.  newLISP has a great function called <b>(parse-xml)</b> that converts an XML tree into a list, but now you just have an unwieldy list.  It&apos;s helpful to be able to extract only the data we want and put it in a simple nested list.<BR><BR>I&apos;ve written a new function in Rockets that lets you do just that.<BR><BR>First, get the data from the RSS feed URL that you want:<BR><BR><code><BR>(set &apos;feed-url &quot <a href='http://penny-arcade.com/feed&quot' target='new'>http://penny-arcade.com/feed&quot</a>;))<BR>(set &apos;rss-result (xml-parse (get-url feed-url)))<BR></code><BR><BR>Now, we want to extract the fields &quot;title&quot;, &quot;author&quot;, and &quot;link&quot; from that feed.<BR><BR><pre><BR>(set &apos;field-result (get-fields-from-rss rss-result &apos;(&quot;title&quot; &quot;author&quot; &quot;link&quot;)))<BR></pre><BR><BR>(field-result) will return the following:<BR><BR><code><BR>((&quot;News Post: The Book Of Divine Wisdom&quot; &quot;tycho@penny-arcade.com (Tycho)&quot; &quot <a href='http://penny-arcade.com/2013/01/25/the-book-of-divine-wisdom1&quot' target='new'>http://penny-arcade.com/2013/01/25/the-book-of-divine-wisdom1&quot</a>;)  <BR> (&quot;News Post: So many games!&quot; &quot;gabe@penny-arcade.com (Gabe)&quot; &quot <a href='http://penny-arcade.com/2013/01/25/so-many-games&quot' target='new'>http://penny-arcade.com/2013/01/25/so-many-games&quot</a>;)<BR>           ...etc ... )<BR></code><BR><BR>If a field isn&apos;t present in the RSS data, (field-result) will populate that part of the list with the &quot;nil&quot; value instead.<BR><BR>NOTE: Remove the spurious &quot;;&quot; characters in the example code here before running it<BR><BR>Happy RSSing! ]]></description>
  </item>
  <item>
    <title>How to implement New/Unread Posts in a forum</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=78</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=78</guid>
    <pubDate>Wed, 16 Jan 2013 14:14:11 +0000</pubDate>
    <description> <![CDATA[ This is a trickier issue than it appears at first.<BR><BR>The obvious solution is to just check the date of the last posted message and compare it with, say, the last time the user logged in.  But in practice this doesn&apos;t work, because you want to view a post and have it removed from your &quot;New&quot; list right away, not at some later date.  You actually have to bite the bullet and store a list of posts that you have read or unread.  I chose &quot;read&quot; because by default users don&apos;t have anything in that list, which is easier to implement.<BR><BR>The list is stored as a string of post Id numbers, delimited by hyphens.  When displaying the list of forum posts, it checks each one to see if the post Id is in your list of read posts, just by doing a (find) search on the string.<BR><BR>That part is easy.  But what about when someone adds a new comment to a thread you&apos;ve read?  Ideally you want it to be bumped back to &quot;Unread&quot; status.<BR><BR>The solution I came up with is to get a list of every user&apos;s Read list whenever someone posts a comment.  Then you loop through it and if you find the Post Id in there, you just snip it out using (replace).<BR><BR>Oh, I also added a &quot;Mark All as Read&quot; button, for people who just want all those pesky &quot;New&quot; icons to go away, RIGHT NOW.  It gets a list of every post and adds them all to your Read list.<BR><BR>Is it as efficient as it could be?  Will it bog down when you have a million users?  I have no idea.  I&apos;ll cross that bridge when I come to it.  For now, it seems to work pretty well. ]]></description>
  </item>
  <item>
    <title>View counts!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=77</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=77</guid>
    <pubDate>Tue, 15 Jan 2013 17:19:09 +0000</pubDate>
    <description> <![CDATA[ I&apos;ve added a small feature that shows the number of views each forum thread or blog post has gained.  Each time you view a thread in the forum view or view a complete blog post by clicking on the link, the number is bumped.<BR><BR>Because this is a new feature, all the old views aren&apos;t counted.  :(  So they are starting at zero.<BR><BR>This did require a change to the database, as I didn&apos;t already have the column &quot;PostViews&quot; in the Posts table.  This can present a problem when people are upgrading from an earlier version of Rockets that doesn&apos;t have that column.  I&apos;ve updated <b>setup-rockets.lisp</b> to create this field when making a new database, but people&apos;s existing databases won&apos;t have it.  I&apos;ll probably have to add a &quot;update database to latest version&quot; script that will just add the missing columns for people with older versions.  One nice thing is that the database doesn&apos;t need any values in there.  It just needs to be altered to add this missing field. ]]></description>
  </item>
  <item>
    <title>Happy New Year and a server upgrade!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=76</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=76</guid>
    <pubDate>Mon, 07 Jan 2013 14:36:31 +0000</pubDate>
    <description> <![CDATA[ Welcome to 2013!  It&apos;s fun living in the future.<BR><BR>I&apos;ve upgraded the server from Ubuntu 10.04 to Ubuntu 12.04 LTS, so please let me know if there are any hiccups or strange behaviors on the site.<BR><BR>I&apos;ll be posting more soon! ]]></description>
  </item>
  <item>
    <title>Towards the creation of newLISP on Rockets installation scripts...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=73</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=73</guid>
    <pubDate>Wed, 12 Dec 2012 15:07:52 +0000</pubDate>
    <description> <![CDATA[ I&apos;m now starting to use Rockets for projects at work, so I need a way to create the user database from scratch.  Anyone wanting to start using the newLISP on Rockets Blog source code will need to do the same thing.  So our desires align!<BR><BR>I&apos;ve created a simple installation script called setup-rockets.lisp.  It needs to be run from the command line:<BR><BR><code>sudo newlisp setup-rockets.lisp</code><BR><BR>This will ask you a few questions (database, name, password, etc) and set up a new database for you with the right tables and create an admin user.  Obviously you never want this to be run by someone else over the web, so make sure that it can&apos;t be viewed over your web server (either by permissions, or by using my Apache .htaccess directive that excludes all files ending in .lisp from being viewed (.lsp files are fine though!)<BR><BR><pre><BR># Prevent framework source from being accessed<BR>&lt;Files ~ &quot;\.lisp$&quot;&gt;<BR>Order allow,deny<BR>Deny from all<BR>&lt;/Files&gt;<BR><BR># Prevent database files from being accessed<BR>&lt;Files ~ &quot;\.db$&quot;&gt;<BR>Order allow,deny<BR>Deny from all<BR>&lt;/Files&gt;<BR></pre><BR><BR>Once the database is created (it will append the &quot;.db&quot; extension as well... you notice I&apos;ve excluded those files so that you can&apos;t download the database from the web or via wget) you need to make sure it has the permissions to read and write by the owner:<BR><BR><pre><BR>chown www-data:www-data DATABASENAME.db<BR>chmod 755 DATABASENAME.db<BR></pre><BR><BR>and you should be ready to go! ]]></description>
  </item>
  <item>
    <title>An easy way to increase your post count...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=72</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=72</guid>
    <pubDate>Mon, 03 Dec 2012 13:28:52 +0000</pubDate>
    <description> <![CDATA[ Is now to post more!<BR><BR>Now comments on blog posts, forum posts, or replies to forum posts will count towards your post count total.  This feature wasn&apos;t implemented before, so I&apos;ve gone ahead and retroactively counted everyone&apos;s posts (thanks to the COUNT(*) features of SQLite) to ensure not a single post of yours goes uncounted!<BR><BR>Post counts are a fun way to keep track of contributions to an online community.  Implementing the +1 bump every time a user posts was quite easy:<BR><BR><pre><BR>; now update the user&apos;s postcount! postcount++!!<BR>(set &apos;UserId Rockets:UserId)<BR>(set &apos;UserPosts (++ Rockets:UserPosts))<BR>(update-record &quot;Users&quot; UserId UserPosts)<BR></pre><BR><BR>I was pretty happy to be able to use the ++ function given that on many online forums, people post things like &quot;Postcount++&quot; when they post.  Of course, this is LISP, so the ++ comes first.  <BR><BR>You can view your post count by going to Edit Profile (click your name on the upper right to pull down the user menu) or simply by viewing a forum thread to see everyone&apos;s post counts!  I didn&apos;t put post counts in the Blog view because blog posts are supposed to be, well, more about the post itself than about everyone increasing post counts.  But if you view a blog thread in Forum view you will see that the appropriate counts have been updated.<BR><BR>At some point I will implement ranks based on postcount, which will also appear in the forum view and in your profile. So get out there and start posting!  ]]></description>
  </item>
  <item>
    <title>Calendars, date-pickers, and your birthday!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=69</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=69</guid>
    <pubDate>Tue, 27 Nov 2012 15:14:43 +0000</pubDate>
    <description> <![CDATA[ Happy Birthday!  Or is it?<BR><BR>It&apos;s handy in web applications to have a way to select dates in a rigid format, and to have a little calendar to make it easier for users to select dates.  I&apos;ve incorporated a plugin for Bootstrap that does just that.<BR><BR>Inside a form, just use the following code:<BR><BR><code>(form-datepicker &quot;Enter your birth date&quot; &quot;date&quot; show-birthdate &quot;dp1&quot;)</code><BR><BR>This will open up a little form box where you can type in a date, or if you click on the date box a calendar pops up.  <BR><BR>To see it in action, go to your User Profile page (click on your name on the upper right) and you can set your birthdate there!  At some point I&apos;ll add a little feature that will send you a Happy Birthday email, just for fun.<BR><BR>When I was implementing this I discovered that SQLite wants dates in a YYYY-MM-DD HH:MM:SS.000 format and this calendar wants it in MM-DD-YYYY format.  It&apos;s quite easy to convert between the two, but I might add some date functions to Rockets to make this easier.  Of course everyone has their own preferred date format, which complicates things still further... ]]></description>
  </item>
  <item>
    <title>Avatar uploads are working!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=68</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=68</guid>
    <pubDate>Mon, 19 Nov 2012 20:52:42 +0000</pubDate>
    <description> <![CDATA[ After a fair bit of fiddling, I&apos;ve gotten avatar uploads working on the newLISP on Rockets blog.  Now you can upload your own image.<BR><BR>The code to display a file upload form looks like this:<BR><BR><pre><BR>(displayln &quot;&lt;p&gt;Upload new avatar (all avatars scaled to 64x64 pixels): &lt;form name=&apos;FileUpload&apos; action=&apos;rockets-avatarupload.lsp&apos; method=&apos;POST&apos; enctype=&apos;multipart/form-data&apos;&gt;&lt;input type=&apos;file&apos; id=&apos;uploadName&apos; name=&apos;uploaded_data&apos; onChange=&apos;this.form.textname.value = this.value&apos;&gt;&lt;input type=&apos;hidden&apos; name=&apos;textname&apos;&gt;&lt;input type=&apos;submit&apos; value=&apos;Upload&apos; name=&apos;submit&apos;&gt;&lt;/form&gt;&quot;)<BR></pre><BR><BR>The form variables are put into the ($POST) tree, along with a variable called &quot;filename&quot; that holds the file name, and &quot;binary-data&quot; that holds the file itself.<BR><BR>To retrieve these from ($POST), just use the following code:<BR><BR><pre><BR>(set &apos;file-name ($POST &quot;filename&quot;))<BR>(set &apos;file-binary ($POST &quot;binary-data&quot;))<BR></pre><BR><BR>Then to save the file , I use the following command:<BR><BR><code>(write-file (string &quot;images/avatars/&quot; file-name) file-binary)</code><BR><BR>One bit of warning: you will need to set the ownership permissions on the directory where you are saving these files to something that the Apache user has write access to.  In Ubuntu this was something like:<BR><BR><code>sudo chown www-data:www-data images/avatars</code><BR><BR>And that&apos;s it!  The avatar images are not scaled when they are uploaded, but they are displayed with fixed dimensions of 64x64 pixels.  This means if you upload a larger image it will look tiny.  In the future I will add a module that automatically resizes files to a dimension of your choice, but for now, try to keep avatars to no larger than 100x100. ]]></description>
  </item>
  <item>
    <title>The feeling of triumph when fixing a stubborn bug...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=67</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=67</guid>
    <pubDate>Tue, 13 Nov 2012 16:26:48 +0000</pubDate>
    <description> <![CDATA[ It&apos;s not quite like winning an Olympic Gold Medal or anything, but it&apos;s a nice feeling.<BR><BR>I was having a very intermittent problem with long posts being truncated.  Most posts are short enough that they didn&apos;t encounter this problem, but longer posts with code would sometimes just cut off randomly.  The weird thing is that if I went back and refreshed the page they would go through.  It wasn&apos;t predictable at all.  Those kind of bugs are the <b>most</b> annoying!<BR><BR>Basically I had some old code that followed a similar technique that Dragonfly used:<BR><BR><pre><BR>(when (&gt; (peek (device)) 0)<BR>	(if (and (read (device) post-buffer $MAX_POST_LENGTH) post-buffer) ; grab all post data, put it in variable &apos;post-buffer&apos;<BR>		(parse-get-or-post post-buffer $POST)<BR>	)<BR>)<BR></pre><BR><BR>The idea is that you&apos;re reading from (device) into a variable called post-buffer.  Hard to figure out what&apos;s going wrong in there!<BR><BR>Not sure how to fix this, I went and looked at the code in Artful Code&apos;s A Better newLISP Web Library: <a href='http://www.artfulcode.net/articles/a-better-newlisp-web-library' target='new'>http://www.artfulcode.net/articles/a-better-newlisp-web-library</a>/<BR><BR>The author had taken a slightly different approach, which I adapted into my framework:<BR><BR><pre><BR>(let ((buffer &quot;&quot;) (post-buffer &quot;&quot;))<BR>	(unless (zero? (peek (device)))<BR>		(while (read (device) buffer $MAX_POST_LENGTH)<BR>			(write post-buffer buffer))<BR>		(parse-get-or-post post-buffer $POST)))<BR></pre><BR><BR>Basically, instead of just reading the (device) once, it CONTINUES to read the (device) and copies whatever it finds into a temporary variable &quot;buffer&quot; that gets appended to the variable &quot;post-buffer&quot; until there is nothing left to read.<BR><BR>It&apos;s nice when things get fixed like this.  It makes me very happy.   ]]></description>
  </item>
  <item>
    <title>MVC code patterns, templates, and complexity</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=65</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=65</guid>
    <pubDate>Thu, 08 Nov 2012 15:15:49 +0000</pubDate>
    <description> <![CDATA[ Today I implemented an entirely different way to view posts and comments, the forum view.  When you view a blog post, the same post also exists in the forums.  In fact, you can click on the &quot;View post in forums&quot; button to toggle the views.<BR><BR>A lot of people would tell you to write this kind of thing using the MVC (model-view-controller) model, or at least use a framework that has a templating system so that you can view the same data differently.  <BR><BR>This is a completely valid perspective and I&apos;m not going to argue otherwise.  MVC is a well-established design methodology and it works pretty well for a lot of different applications.  Templates seem like they could be really useful.<BR><BR>I didn&apos;t implement the forum view this way, however.  I just had a toggle variable called (forum-view-post) and checked to see if it was true.  If it was, then I executed a different code block.  The real danger here is code duplication, which is something we always want to avoid.  <BR><BR>The thing is, implementing this very different view took only <i>ten lines of code</i>.<BR><BR><pre><BR>(displayln &quot;&lt;h3&gt;&quot; (list-post-data 3) &quot;&lt;/h3&gt;&quot;)<BR>(set &apos;header-list &apos;(&quot;Author&quot; &quot;Message&quot;))<BR>(set &apos;post-data (list (string &quot;&lt;img src=&apos;images/avatars/&quot; (author-avatar (list-post-data 1)) &quot;&apos;&gt;&lt;br&gt;&quot; (author-name (list-post-data 1))) (format-for-web (list-post-data 4))))<BR>(set &apos;PostId (int (list-post-data 0)))<BR>(set &apos;post-data (list post-data)) ; okay these two lines of code are duplicated... I can live with it for now<BR>(set &apos;post-comments (get-record &quot;Comments&quot; PostId))<BR>(if post-comments (begin<BR>	(dolist (p post-comments)<BR>		(push (list (string &quot;&lt;img src=&apos;images/avatars/&quot; (author-avatar (p 2)) &quot;&apos;&gt;&lt;br&gt;&quot;(author-name (p 2))) (format-for-web (p 5))) post-data -1)) ; add each comment to the thread<BR>	))<BR>(display-table header-list post-data &quot;striped&quot;) <BR></pre><BR><BR>Okay, so two lines of code are duplicated in the alternate (blog) view, which I had already written.  If it was much more than this, maybe I&apos;d write a function and move it outside the block so that I didn&apos;t have duplicate code.  Obviously I don&apos;t want to have to change things multiple times every time I change the view.  But these two lines only extract the comment data from the database, so I wouldn&apos;t be changing these anyway.<BR><BR>Now, let&apos;s say I wrote this using a template system, or with MVC, or both.  It would be a <i>lot</i> more than ten lines of code.  I would have to learn another language (the templating language) and I would have to write a bunch of classes and methods and make sure they all work properly together, maybe writing a bunch of unit tests to ensure I don&apos;t break anything if I change the contracts between the model, view, and controller.  More code equals more opportunities for bugs.  In fact, the number of lines of code is the <i>only</i> aspect of development that has a strong correlation with the number of bugs.  Everything else is too hard to measure. Fewer lines of code also take less time to write, in general.  So all else being equal, wouldn&apos;t you want to have fewer lines of code to do the same thing?<BR><BR>As far as templates go, they make a lot of sense in a big company where there is a whole department doing user interface design and another department doing coding.  The designers can learn the templating language and HTML, and not have to learn anything else.  For my personal development, I am both the interface designer and the developer.  <BR><BR>The newLISP code <b>is</b> my templating language.  I don&apos;t want to have to learn another language if I can just keep everything together.  Overall, the arguments for using MVC and templating work better for larger projects with lots of people.  newLISP on Rockets is optimized for very small development teams, including projects where the team is only one person.  In these cases, simplicity almost always wins out over complexity. ]]></description>
  </item>
  <item>
    <title>Linking a blog to a forum...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=59</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=59</guid>
    <pubDate>Tue, 06 Nov 2012 15:17:32 +0000</pubDate>
    <description> <![CDATA[ Blogs and forums are two different things, but they don&apos;t have to be.<BR><BR>I&apos;m adding a forum to the Rockets blog, where any registered user will be able to post on any topic.  Each new blog post will appear on the forum, and any comments added in the forum will be reflected in the blog itself.  But the inverse is not true-- any new forum post will not appear on the blog.  This allows other users to start discussions and interact with each other without interrupting the blog itself.<BR><BR>The way I do this is to add a new column called &quot;PostType&quot; that can be either &quot;Blog post&quot; or &quot;Forum post&quot;.  The former will be retrieved by the main page, while the latter is retrieved by the forum page.<BR><BR>I&apos;m also using my new (display-table) function to display the forum posts. ]]></description>
  </item>
  <item>
    <title>Tables and Avatars...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=53</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=53</guid>
    <pubDate>Fri, 02 Nov 2012 23:27:05 +0000</pubDate>
    <description> <![CDATA[ A couple of additions today...<BR><BR>First, a Table function that prints some nicely-formatted HTML tables.<BR><BR><pre><BR>(display-table list-of-headers nested-list-of-data &quot;optional form styling&quot;)<BR><BR>striped - alternates rows in grey <BR>bordered - adds borders and rounded corners to the table <BR>hover - enables hover state on table rows when mousing over <BR>condensed - more condensed style of table<BR></pre><BR><BR>This is a neat way of displaying tabular data in a pretty way, just by passing in lists.  <BR><BR>The other thing is that I&apos;ve changed the formatting of comments to include user avatars to the left of each comment.  Unfortunately I didn&apos;t have time to get avatar uploading working. That will have to wait for next week! ]]></description>
  </item>
  <item>
    <title>Utilizing the power of LISP macros</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=13</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=13</guid>
    <pubDate>Fri, 02 Nov 2012 17:24:39 +0000</pubDate>
    <description> <![CDATA[ Today&apos;s function turned out to be well suited for a macro.  (create-record) takes a couple of arguments.  The first is a string which holds the name of the table you are updating.  The rest is kind of cool.  You put in a bunch of variable names--any number is fine--and what you do is make the variable name the same as the FIELD name in your table.  Then the macro takes the names and values of these variables and constructs a valid SQL statement (after filtering each value for SQL injection issues)<BR><BR>So, for example, to add a post in this blog, I just have to write:<BR><BR><code>(create-record &quot;Posts&quot; Id PosterId PostDate PostSubject PostContent)</code><BR><BR>and it generates a valid SQLite query to insert the values into the field names that are the variables Id, PosterId, etc.<BR><BR>The magic comes from newLISPs (sym) function, which converts a string into a valid symbol, and the (args) feature of newLISP macros, which allow a dynamic number of arguments to be passed to the macro.<BR><BR>Here&apos;s the code that converts the variable names into symbols:<BR><BR><pre>(dolist (s (rest (args)))<BR>  (set &apos;temp-index-num (string &apos;idx)) ; we need to number the symbols to keep them in the correct order<BR>  (if (= (length temp-index-num) 1) (set &apos;temp-index-num (string &quot;0&quot; temp-index-num))) ; leading 0 keeps the max at 100.<BR>  (sym (string temp-index-num s) &apos;DB))<BR></pre><BR><BR>I have to prepend a numeric value to the symbols to ensure they get posted into the list (symbols &apos;DB) in the correct order-- right now the limit is 100 fields but I could easily bump this to 1000 if I need to, or even higher... I want to keep this limit in here for now as a kind of sanity check though.<BR><BR>So, the C part of CRUD is done.. just three more parts to go!   ]]></description>
  </item>
  <item>
    <title>I&apos;ve got a Rocket!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=52</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=52</guid>
    <pubDate>Thu, 01 Nov 2012 21:42:04 +0000</pubDate>
    <description> <![CDATA[ Some sites have a mascot.  Okay, we have a rocket, let&apos;s call him Rocketty.  Done.  <BR><BR>Now all we need is a theme song.<BR><BR><iframe width="560" height="315" src="http://www.youtube.com/embed/rJppnG1tflU" frameborder="0" allowfullscreen></iframe><BR><BR>This is another UBB code enabling the user to embed YouTube videos.  Just use the tags [ youtube ] and [ /youtube ] (without the spaces) and in between, put the alphanumeric string of that video (eg: rJppnG1tflU)   ]]></description>
  </item>
  <item>
    <title>I have an About page!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=35</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=35</guid>
    <pubDate>Thu, 01 Nov 2012 17:21:16 +0000</pubDate>
    <description> <![CDATA[ It&apos;s no Cave Troll, but it will have to do.<BR><BR>Click the &quot;About&quot; link on the top bar to read it! ]]></description>
  </item>
  <item>
    <title>Why Rockets?</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=37</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=37</guid>
    <pubDate>Thu, 01 Nov 2012 17:20:29 +0000</pubDate>
    <description> <![CDATA[ An existential question, indeed...  <BR><BR>For no apparent reason I decided to write a whole essay about it: <a href='http://newlisponrockets.com/rockets-why.lsp' target='new'>http://newlisponrockets.com/rockets-why.lsp</a> ]]></description>
  </item>
  <item>
    <title>Editing!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=51</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=51</guid>
    <pubDate>Thu, 01 Nov 2012 17:17:39 +0000</pubDate>
    <description> <![CDATA[ So, now we have the final U in CRUD done, and I can finally edit posts. YOU can&apos;t edit comments yet, but that&apos;s coming soon, probably tomorrow.<BR><BR>That&apos;s fun. EDITING ROCKS! It&apos;s also a really neat macro that makes it pretty easy to do SQL update statements.<BR><BR>Here&apos;s another neat thing: Basically, I use the exact same statement to create and update a post:<BR><BR><code>(update-record &quot;Posts&quot; Id PosterId PostDate PostSubject PostContent) ; It&apos;s the U in CRUD!</code><BR><BR><code>(create-record &quot;Posts&quot; Id PosterId PostDate PostSubject PostContent) ; It&apos;s the C in CRUD!</code><BR><BR>There&apos;s a lot of stuff going on behind the scenes to translate the above into two very different SQL statements. Basically the Id in the first is to CHECK for Id&apos;s value, and in the second statement it is to SET Id to that value. I like the symmetry, ]]></description>
  </item>
  <item>
    <title>Parameterizing SQL queries</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=50</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=50</guid>
    <pubDate>Wed, 31 Oct 2012 00:37:48 +0000</pubDate>
    <description> <![CDATA[ Sometimes SQL injection comes in tricky forms.  Often attackers will add on extra junk in the URL to try and confuse SQL into doing something it wasn&apos;t intended to do.  For example, if the URL for page 2 is:<BR> <a href='http://newlisponrockets.com/rockets-main.lsp?p=2' target='new'>http://newlisponrockets.com/rockets-main.lsp?p=2</a><BR><BR>an attacker might try something like<BR> <a href='http://newlisponrockets.com/rockets-main.lsp?p=2' target='new'>http://newlisponrockets.com/rockets-main.lsp?p=2</a> OR 1=1<BR><BR>to try and break the code or inject some other SQL into the query by adding these commands with spaces.  <BR><BR>I&apos;ve added a function called (force-parameters) that makes it easy to prevent this.  For example, to get the page number from the URL, I used to call ($GET "p"), which in this case would return "2 OR 1=1".<BR><BR>Now, I use the code:<BR><BR><code>(set &apos;current-page (force-parameters 1 ($GET "p"))) ; we only need the first part, ignore anything else</code><BR><BR>which takes only the first parameter from the URL.  You can add as much extra junk after it, but it will only take the "2". ]]></description>
  </item>
  <item>
    <title>Testing UBB code</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=49</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=49</guid>
    <pubDate>Mon, 29 Oct 2012 23:21:47 +0000</pubDate>
    <description> <![CDATA[ Just a little <b>bold</b> and <i>italics</i> and <u>underlines</u><BR><BR>and some code samples:<BR><BR><code>(format-for-web str-input-text)</code><BR><BR>The above code now translates these UBB codes into HTML.  Actual HTML is converted to its literal equivalent to avoid cross-site scripting issues. ]]></description>
  </item>
  <item>
    <title>Welcome emails for new users!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=48</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=48</guid>
    <pubDate>Mon, 29 Oct 2012 21:41:28 +0000</pubDate>
    <description> <![CDATA[ When I started this little thing a month and a half ago, I didn&apos;t expect anyone to notice it right away. The Internet is a big place and Rockets is, for now, quite small.<BR><BR>But a few people have found their way here (welcome guys!) and so I now need a way to send some welcome emails for new users.<BR><BR>I&apos;ve added a function called (send-mail), which sends an email to a given address. Behind the scenes it uses the Unix command sendmail, so you will need to have that installed on your server (simply type "sudo apt-get install sendmail" on Ubuntu or Debian). <BR><BR>To avoid emails falling into spam traps, you need to be sending from a valid email address that has the same domain as the server that is sending it. The (send-mail) function will take care of all the headers and things automatically.<BR><BR>For example, for new users, I simply use:<BR><BR>(send-mail UserEmail "newlisponrockets@newlisponrockets.com" "Rocket Man" "Welcome to the newLISP on Rockets blog!" welcome-email)<BR><BR>where welcome-email is the string of the body of the email. ]]></description>
  </item>
  <item>
    <title>Documentation!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=46</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=46</guid>
    <pubDate>Tue, 23 Oct 2012 00:02:56 +0000</pubDate>
    <description> <![CDATA[ Documentation is something I have a particular fondness for.  I actually got my start in the software industry as a technical writer, so I appreciate it when things are well-documented.  Of course now that I am a developer I find writing documentation to be a chore!<BR><BR>The way I&apos;ve done documentation in Rockets is to automatically generate it from the comments in the core file that contains all of Rockets&apos; functions.  However in order for this to work I had to go back and clean up and standardize all the comments, something that I had been putting off.  Oh well, sometimes chores need to be done!<BR><BR>One thing I always disliked about most programming documentation is the requirement to understand and translate some weird meta-language or syntax for the usage of each statement.  Usually it was easier to just look at the example and figure out what the author meant.  So for Rockets, all my usage statements are in fact examples, albeit using names and strings that describe their actual function.  So for example (open-database "database name") is both the usage and the example of opening a database. ]]></description>
  </item>
  <item>
    <title>How to make a custom 404 Not Found page</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=45</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=45</guid>
    <pubDate>Mon, 22 Oct 2012 21:33:43 +0000</pubDate>
    <description> <![CDATA[ This is something really simple, the perfect assignment for a Monday morning.<BR><BR>Go to your site&apos;s root directory (usually /var/www) and edit the .htaccess file (type sudo nano .htaccess)<BR><BR>Add the following line to the end of the file:<BR><BR>ErrorDocument 404 /rockets-404.lsp<BR><BR>Now any 404 (page not found) errors will redirect to this page instead of displaying the generic Apache error. ]]></description>
  </item>
  <item>
    <title>Commenting is live!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=44</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=44</guid>
    <pubDate>Fri, 19 Oct 2012 23:28:16 +0000</pubDate>
    <description> <![CDATA[ This would be a PERFECT message to test out adding comments to.. if you know what I mean.  Hint, hint. ]]></description>
  </item>
  <item>
    <title>User Registration is live!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=43</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=43</guid>
    <pubDate>Thu, 18 Oct 2012 22:53:16 +0000</pubDate>
    <description> <![CDATA[ Yes, with Rocket Captcha(tm) and everything!<BR><BR>You can&apos;t do anything once you sign in (like post messages or anything) yet but... you&apos;ll have an account! ]]></description>
  </item>
  <item>
    <title>What page am I on?</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=42</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=42</guid>
    <pubDate>Thu, 18 Oct 2012 18:15:09 +0000</pubDate>
    <description> <![CDATA[ Sometimes you want your application to remember where you were, but the application wants to redirect you to somewhere else.<BR><BR>This is most annoying when you sign in.  You probably want to stay on the page you were on instead of being redirected back to the main page.<BR><BR>Rockets adds a global variable called (active-page).  You have to set it before you call the navigation bar so it knows which page to highlight.  But it also passes this variable as a hidden field in the navigation bar itself, alongside the user email and password, so that the verification script (rockets-verify.lsp) can redirect you back to that page if you either succeeded or failed in signing in. ]]></description>
  </item>
  <item>
    <title>Paging all paging code!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=41</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=41</guid>
    <pubDate>Tue, 16 Oct 2012 17:58:41 +0000</pubDate>
    <description> <![CDATA[ Paging code is really easy in SQLite.  You do a SELECT statement as normally but add the LIMIT clause with two numbers separated by a comma. The first number is the offset, aka where you start from, and the second number is the number of results you want back.  So if you wanted ten results starting from the thirtieth, you just SELECT ... LIMIT 30,10 and that&apos;s it!<BR><BR>Displaying the current paging links is something I might want to do a lot, so I made a function in Rockets to do it.  The function works like this:<BR><BR>(display-paging-links int-start-page int-total-pages int-current-page str-page-url)<BR><BR>So to display the top ten pages you&apos;d call (display-paging-links 1 10 1 "rockets-main").<BR><BR>Neat and easy! ]]></description>
  </item>
  <item>
    <title>Do I write a new function or put it in a (display-partial)?</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=40</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=40</guid>
    <pubDate>Mon, 15 Oct 2012 23:14:11 +0000</pubDate>
    <description> <![CDATA[ Eliminating duplicate code is a great thing.  If you have code that is duplicated on many pages, if you want to change it you have to remember to change it on all your pages.<BR><BR>I originally made a framework function (display-navbar) that displays a navigation bar and sign-in form.  This was great, but (display-navbar) needs to take a list as an argument to decide what menus to actually show.  I didn&apos;t want to repeat this list on each page, but I also needed a way to show which page was currently active.<BR><BR>One way would be just to define a new function, (display-rockets-nav "active page") that would then call (display-nav) and specify which page is actually active.  But then I would want to make sure this function is defined on every page.  Well, I already have a set of common functions in the partial "rockets-common-functions.lsp".  I could just put it in there.<BR><BR>The other option is to define a new partial page, "rockets-navbar.lsp", and call this partial each time.  Which approach is better?  They both require the same amount of code (I have to add a line to either call the function or display the partial).  The only real difference is that if I go the function route I would have to have two functions, one in the framework, and one in the application, that had similar names, and I&apos;d have a function calling a function.  If I put it in a partial file, it looks like it is doing something different.<BR><BR>Ultimately it&apos;s an aesthetic choice.  If you make your own application you might decide to do it differently.  I might even change my mind at some point! ]]></description>
  </item>
  <item>
    <title>Salted cookies! Yum!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=36</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=36</guid>
    <pubDate>Wed, 10 Oct 2012 20:56:22 +0000</pubDate>
    <description> <![CDATA[ Cookie security is something many sites don&apos;t bother with, because who would ever fake a cookie?  Well, as it turns out, a lot of people could do just that.<BR><BR>Cookie security best practices have been known for a while.  This article from 2005 lays them out pretty nicely: <a href='http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice' target='new'>http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice</a>/<BR><BR>Basically, you want to have a random number as your cookie, but then the value should not just be the user Id.  It should be hard to guess.  And what if a user registers and then copies your carefully-selected random number cookie but just changes the user id?  Then they could log in as any user they wanted!<BR><BR>So what we do is add some salt to the cookie in the form of ANOTHER random number, each one unique to each user.  The salt is stored in the user database, so it isn&apos;t available to the public.  This makes every cookie unique for each user.<BR><BR>You also want to be running everything under SSL (aka https) to avoid issues with people stealing cookies with things like FireSheep over WiFi connections, but that&apos;s something that can be up to the site administrator. ]]></description>
  </item>
  <item>
    <title>Redirections ahoy!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=34</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=34</guid>
    <pubDate>Tue, 09 Oct 2012 23:51:50 +0000</pubDate>
    <description> <![CDATA[ I have implemented redirections, which are basically just HTTP status codes that point the site to a new page.  The command is:<BR><BR>(page-redirect url-of-page-to-redirect)<BR><BR>The way it works is that if the logic in your code (say, successfully signing in) should then move you to another page, it does so and immediately exits, without printing anything else, even if you have put (display-page) later on in the page.  So, in our example, if the username and password are valid, it just puts you back to the main page.  If they are not valid, it will display a message normally with (display-page). ]]></description>
  </item>
  <item>
    <title>Welcome to the front page!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=33</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=33</guid>
    <pubDate>Thu, 04 Oct 2012 22:10:57 +0000</pubDate>
    <description> <![CDATA[ Since I&apos;ve disabled non-admins from posting new blog entries, I thought it was safe to move the newLISP on Rockets Blog to the front page of newlisponrockets.com.  Wow, that&apos;s a lot of saying newlisp on rockets.  Did I mention my email was newlisponrockets@newlisponrockets.com?  <BR><BR>newlisp on Rockets. ]]></description>
  </item>
  <item>
    <title>ONLY I MAY POST!!!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=32</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=32</guid>
    <pubDate>Thu, 04 Oct 2012 20:44:36 +0000</pubDate>
    <description> <![CDATA[ Muahahahaa!  Mine is an evil laugh!<BR><BR>No, this is just a side-effect of getting user sign-in working.  I have the only account, since I haven&apos;t done the Registration part yet.  <BR><BR>The plan is that only I will be able to make new blog posts, but anybody who has registered will be able to comment on blog posts.   ]]></description>
  </item>
  <item>
    <title>Hashing and salting user passwords</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=31</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=31</guid>
    <pubDate>Thu, 04 Oct 2012 00:01:50 +0000</pubDate>
    <description> <![CDATA[ It&apos;s generally considered to be a bad idea to keep clear-text passwords in your database.  If the database is ever compromised, hackers will have everyone&apos;s passwords.<BR><BR>What most sites do is hash the passwords using a one-way algorithm, like SHA1, which is a 160-bit encryption.  Newlisp has a SHA1 function included in the module crypto.lsp.<BR><BR>Unfortunately, hackers these days use dictionary-based attacks, where they take every word in the dictionary (and many common password combinations that include numbers or years) and then just run them through SHA1 or the equivalent, and check to see if they match the compromised stored password hash.<BR><BR>To prevent this, people have been adding salt to the passwords and then encrypting THAT.  Salt is just a random number.  Each user gets its own Salt, which is stored in the user database.  This way, attackers would have to run separate dictionary attacks for every user, and that&apos;s assuming they know the salting algorithm.<BR><BR>I found a great article on password security here:  <a href='http://phpsec.org/articles/2005/password-hashing.html' target='new'>http://phpsec.org/articles/2005/password-hashing.html</a>  <BR><BR>It outlines the whole process and shows how to handle it in PHP.  I&apos;m building in the equivalent in Rockets using newLISP code, which will be part of the user sign in process. ]]></description>
  </item>
  <item>
    <title>Cookies! Fresh out of the oven!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=29</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=29</guid>
    <pubDate>Wed, 03 Oct 2012 21:28:17 +0000</pubDate>
    <description> <![CDATA[ After much soul-searching, I went ahead and implemented the delayed-write method I talked about in my earlier posts.<BR><BR>At first I tried to overload (print) and (println) and it worked but jumping in and out of different contexts made messed up my ($POST) functions, and I thought I&apos;d simplify my life by just defining new functions: (display) and (displayln).  Then at the end you (display-page).  You can also (display-image) and (display-post-box).  Kind of a theme going there.<BR><BR>Anyway, (set-cookie) now adds a cookie to the header that will get posted when the page itself is displayed.  It seems to be working, so hopefully I can now work on getting user sign-in happening on the Rockets blog! ]]></description>
  </item>
  <item>
    <title>Posted from my iPhone</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=28</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=28</guid>
    <pubDate>Thu, 27 Sep 2012 00:11:21 +0000</pubDate>
    <description> <![CDATA[ Yes. It was.  ]]></description>
  </item>
  <item>
    <title>Try it on your iPhone...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=27</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=27</guid>
    <pubDate>Wed, 26 Sep 2012 23:11:12 +0000</pubDate>
    <description> <![CDATA[ <BR>Thanks to Bootstrap&apos;s "reactive" ability, you&apos;ll notice it gets automatically reformatted and the menus work differently.<BR><BR>I think it&apos;s pretty neat. ]]></description>
  </item>
  <item>
    <title>Fancy graphics!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=26</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=26</guid>
    <pubDate>Wed, 26 Sep 2012 23:10:52 +0000</pubDate>
    <description> <![CDATA[ Courtesy of Bootstrap, the open-source CSS and Javascript library released by Twitter. <BR><BR>Bootstrap is based on jQuery, which I use a lot and which will be fully integrated into Rockets. ]]></description>
  </item>
  <item>
    <title>YAY!!!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=25</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=25</guid>
    <pubDate>Tue, 25 Sep 2012 23:56:24 +0000</pubDate>
    <description> <![CDATA[ Small and fast.... ]]></description>
  </item>
  <item>
    <title>Benchmarking...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=24</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=24</guid>
    <pubDate>Tue, 25 Sep 2012 22:29:23 +0000</pubDate>
    <description> <![CDATA[ It&apos;s in there.  Scroll down to the bottom of the page. ]]></description>
  </item>
  <item>
    <title>Cookie Conundrum Continues...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=23</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=23</guid>
    <pubDate>Tue, 25 Sep 2012 22:06:13 +0000</pubDate>
    <description> <![CDATA[ I&apos;ve been thinking about the Cookie Conundrum and I think it goes beyond just Cookies...<BR><BR>If I want to do a redirect on a page, as Dragonfly does with Response:redirect (something I use all the time) I have to set the headers to be a 302 Redirect.  Again, these headers have to be sent before any other text is shown, so it has to be printed at the beginning.<BR><BR>I have changed the way Rockets works to use the Dragonfly model of just loading everything into a big global variable called STDOUT, then delaying printing until the end where you print the headers first and then STDOUT.  Only I can&apos;t force the delay because there isn&apos;t a main program in charge of loading each page, so you have to remember to add the new function (display-page) at the end of your pages for it to work.<BR><BR>Hmm. Not sure about this.  I&apos;ll think about it some more. ]]></description>
  </item>
  <item>
    <title>Thinking about cookies...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=22</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=22</guid>
    <pubDate>Tue, 25 Sep 2012 00:07:42 +0000</pubDate>
    <description> <![CDATA[ In order to get separate users to sign on and post messages, I need to set some cookies.  This leads me to what I call a Cookie Conundrum.<BR><BR>I can define a function to set cookies that is executed somewhere in the page (like rockets-main.lsp) But cookies are set in the header, using the line Set-Cookie.  The header is the first thing printed out by the script, and I won&apos;t know what the cookie is until later in the script.<BR><BR>What Dragonfly does is caches everything being (print)ed and (println)ed into a big old global variable called STDOUT.  Then at the very end of the script it prints the headers (which have already been calculated by the script) followed by STOUT.  This involves overriding (changing the default behavior) of (print) and (println).  I could do that, but is there a way to do it differently?  Can you set a cookie and somehow have it remember to print that cookie in the next header on the following page?  <BR><BR>It&apos;s something to think about... ]]></description>
  </item>
  <item>
    <title>It&apos;s fast enough...</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=21</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=21</guid>
    <pubDate>Fri, 21 Sep 2012 06:49:09 +0000</pubDate>
    <description> <![CDATA[ Said Han Solo. <BR><BR>No, I&apos;m totally going to add that stuff. Very cool.  ]]></description>
  </item>
  <item>
    <title>numbies5</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=20</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=20</guid>
    <pubDate>Fri, 21 Sep 2012 00:01:21 +0000</pubDate>
    <description> <![CDATA[ There&apos;s no millisecond thingy to say how fast this or how many resources were used in its making. ]]></description>
  </item>
  <item>
    <title>foursies</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=19</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=19</guid>
    <pubDate>Tue, 18 Sep 2012 00:17:03 +0000</pubDate>
    <description> <![CDATA[ you see, that&apos;s why I can&apos;t be left alone with a programming language, I don&apos;t know shit.<BR><BR>Since we all live as RocketMan - numbies will be my sig<BR> ]]></description>
  </item>
  <item>
    <title>Spell check </title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=18</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=18</guid>
    <pubDate>Tue, 18 Sep 2012 00:14:30 +0000</pubDate>
    <description> <![CDATA[ That service would be provided by your web browser... :) ]]></description>
  </item>
  <item>
    <title>threesies</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=17</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=17</guid>
    <pubDate>Tue, 18 Sep 2012 00:12:14 +0000</pubDate>
    <description> <![CDATA[ Well, tried to just enter something in the top box and got sent away but now I am back about to make a non historical supporting post. There&apos;s spell check in here too?<BR><BR>How cool is that? ]]></description>
  </item>
  <item>
    <title>Where&apos;s the Code?? WHERE&apos;S THE CODE???</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=15</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=15</guid>
    <pubDate>Mon, 17 Sep 2012 23:28:59 +0000</pubDate>
    <description> <![CDATA[ This, apparently, being the first thing that gets asked.<BR><BR>Well, it&apos;s not much, but it&apos;s here:<BR> <a href='https://github.com/newlisponrockets/newLISP-on-Rockets' target='new'>https://github.com/newlisponrockets/newLISP-on-Rockets</a> ]]></description>
  </item>
  <item>
    <title>testing</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=14</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=14</guid>
    <pubDate>Mon, 17 Sep 2012 21:53:14 +0000</pubDate>
    <description> <![CDATA[ Encoding fun...<BR><BR>What happens if someone puts in a URL?  The framework should translate the special characters, but it is the blog software itself that should translate it into a clickable link.  <BR><BR>Of course, that doesn&apos;t mean I can&apos;t make a function to turn URLs into links automatically (and do other post-entry formatting of blog post text) and include it in Rockets...<BR> <a href='http://arstechnica.com/science/2012/09/curiosity-rolls-on-as-instrument-checkout-continues-on-mars/' target='new'>http://arstechnica.com/science/2012/09/curiosity-rolls-on-as-instrument-checkout-continues-on-mars/</a> ]]></description>
  </item>
  <item>
    <title>The very first post on the newLISP on Rockets Blog!</title>
    <link>http://newlisponrockets.com/rockets-item.lsp?p=0</link>
    <guid>http://newlisponrockets.com/rockets-item.lsp?p=0</guid>
    <pubDate>Thu, 13 Sep 2012 23:01:09 +0000</pubDate>
    <description> <![CDATA[ Wow, this is kind of historic! This is the very first post on the newLISP on Rockets blog. Right now Rockets is barely functional (version 0.04!) but it&apos;s just enough to host itself and handle input to forms and connect to a SQLite 3 database. <BR><BR>It&apos;s nothing earth-shattering so far, but I want to start "eating my own dogfood" as it were, so this blog will be running on Rockets from the very beginning. As I add features, I&apos;ll post about them in the blog. ]]></description>
  </item>
</channel>
</rss>