For being a piece of software that is supposed to HELP document PHP code, it’s documentation sure is awful. I can’t seem to find anything I’m looking for. Like, available configuration options for an INI file. Or, how to specify an alternate template data directory.
January, 2004:
just my luck
Jess and I have decided to buy a house. We had decided this before, but didn’t have the time to do it in, so now we’re starting again. However, because of our price range, I’m having a hard time finding anything special or different. But three or four days ago, I found almost everything I was looking for in a home. Jess really liked it too. But I wasn’t too sure about the area. I told my Dad what I thought of it, showed him pictures, and he was very impressed. So, last night, on our way home, Jess and I drove by it. It is in a GREAT neighboorhood. I picked up a flyer and when I got home I went to the realtor’s website. Next to the property, the site says "Sale Pending".
I’m not sure what that means (did someone make an offer? was an offer accepted? is paperwork actually being filled out? what?) but it’s a bit upsetting because we both really liked it. None the less, we’ll keep looking.
It may be for the best since our lease isn’t up until September. Breaking the lease here might not be a good idea since we currently receive consession and would have to repay all of it (to the tune of about $300/month). We would have to pay about $3000 to get out of our lease.
Inklog: what is it.. part 2
I have been made aware that it still isn’t very clear WHAT Inklog is. So, I’d like to submit a better explanation.
Inklog is really two things.
1) It is a framework for developers to use to create applications in a
simple efficient manner that removes the trouble of dealing with
template engines, configuration, data storage, and other annoyances. It
is a framework that, uses the relationships of various objects to infer
meaning and, therefore functionality.
2) It is a collection of applications created in this framework all running together.
When I started writing Inklog, my goal was to get #2. However, in the end, I realized that required me to write #1.
If you’re a developer, you care about #1. If you’re an end user, you care about #2.
At this point in the game, I’m still working on #1 while keeping in mind the goal of #2.
Inklog is similar to any of the millions of application frameworks that are out there today. It’s difference lies in the fact that it intends to allow simple integration of remote and unrelated components by non-programmer end-users. It takes an object oriented approach (in both code, and in the way data
is stored and represented) to accomplish a tight integration of
components. Inklog’s goal is to force component authors to write in
such a way that their methods, objects, and functionality are reusable
throughout all the other applications with very little knowledge
required.
In a nutshell, the goal is to make it very easy for people who are only
slightly experienced with all things technical to use components
created by seasoned programmers in a manner which is consistant with
the look and feel of their current site.
Let me give you an example. Let’s say I want to track the weather in my
area. So I use Inklog and create an entire system to store historical
weather data for my area and allow me to retrieve it and sort it and
graph it a million different ways. Once this module is built and
available to the public, it opens up a whole new realm of data for
every Inklog user. Let’s say that I just want to display the current
weather on the front page of my blog. That’s no problem, because of the
way Inklog forces programmers to write, I can simply install one or two
pieces of the entire weather system and have a functioning weather box
on my front page. Additionally, because of the integrated theming and
templating, when I install that weather box on my front page, I am able
to make it look exactly as I desire it to without editing a single line
of PHP.
Take, for example, the blogging and image gallery world. There are great
blogging scripts out there (movable type, bblog, wordpress, etc).. and
there is at least one really good image gallery script (gallery).
However, the two don’t interact at all. First of all, they don’t look
even remotely the same and, trying to get gallery to look like anything
other than a colorized version of gallery is close to impossible
without really digging in to the code. Secondly, trying to get my most
recent gallery image into a box in the corner of the top of my weblog
page requires a good amount of PHP coding and internal knowledge of
both the blogging software and the gallery software. Inklog aims to
defeat that requirement.
It does so by making each element of a system nothing more than an
object. The way it is designed almost forces a user to program this
way. To use Inklog and NOT program this way would actually require MORE
work than not using Inklog at all. And, because everything is instantly
templatable and configurable and authenticated, the site owner using
these components is capable of making things work exactly as she would
like, without needing to code even one line of PHP code.
The Inklog framework will excel at enabling applications that primarily
store and present data (like a weblog, an image gallery, a discussion
forum, a software repository, a file trading site, a bug tracking
program, a shopping cart, etc) as opposed to applications that
primarily compute or convert data (like… seti, image editing
applications, RSS readers, etc). It isn’t that Inklog can’t do those
other things… it just doesn’t really make them A LOT easier… unless
of course it is desired that the output be themable/templatable, in
which case, that alone is enough incentive to use Inklog.
Because of the design of Inklog everything inside of it is an object that can be accessed and displayed in any fashion from within any other object. Let me give you an example.
Let’s create an image gallery application. First we make a "gallery" object. It has properties like "description". It contains things like "album objects". It has actions or methods like "view" or "create album". Next we make an "album" object. It has properties like "description". It contains things like "image objects". It has actions of methods like "view" or "create image". Next we make an image object. It had properties like "description", "image data", "width", "height", "format", "location", "subject", etc. It doesn’t contain any objects at all. It has methods like "view". These three data types and their associated methods and templates work together to provide you with a method of creating an image gallery. When "viewed" the gallery object displays a list of its albums. When "viewed" an album object displays a list of its images. When "viewed" an image object displays an image to the user.
Now let’s create a weblogging application. First we make an "article" object. It has properties like "author", "exceprt" and "content" and methods like "view". That’s all this takes. When viewed, the "article" object displays the content as defined in the site templates.
Now let’s create a comment box application. First we make a "comment box" object that merely holds comments. It would have properties like "active". It would have actions like "view" and "add comment". It would hold "comment objects". Next we create a "comment" object. It would have properties like "author" and "text" and "title". It can hold other comment objects (for replies). It would have properties like "view" and "get replies" and "add comment". Done.
So far so good… now here’s the fun. If I create a "comment box" object inside of my "image" object from the gallery application, what happens? That’s right… now people can comment on the image. It’s that simple. Even though the original author of the "gallery" applicaiton didn’t intend to enable comments, an average user is able to take two unrelated components and connect them all using the same look and feel.
It gets even more interesting. Say someone else creates a "shopping cart" application. The shopping cart application can be written in such a way that it doesn’t have to know anything about what it’s selling and it can sell any type of existing object. What it does do it add properties to that object with the information it needs. So, say I want to sell my photographs that are in my gallery. Through the "shopping cart" application, I would make a particular gallery item "sellable". I would supply a "price" and perhaps a "shipping/handling charge". Now the item is sellable and can be held in a cart. Additionally, if I so desire, my image gallery can now access that price and inform the users browsing the gallery that a particular image is for sale at a certain price.
Everything works together because everything is stored in the same way. Because of this shared data model, all components can ensure that they know how to access other elements in the system. Additionally, they know how to render them and how to annotate them. And all of this is done in a templatable themable fashion.
Inklog: three schools of thought
This is a lot easier to explain now that code is available. In Inklog, each all data items are Nodes. However, in order to extend the functionality of what a "node" is, this basic, generic, node is expected to be extended. In fact, the default actions and methods within a generic node return error messages stating that this object needs to be extended to function properly. When an object is extended (like a page node) it gains additional properties and methods (which are data objects). And that’s where the problem lies. There are three ways to do this.
1) The first method is to inflate all of the properties when the node is inflated. This requires a database hit for each property and additional memory consumption to store that data. This seems especially wasteful when, for instance, the user is trying to access the "description" of a 100MB image. There is no point in loading the image data from the database and no point in storing it in memory since it’s never going to be used. The benefit to this method is that the object is real and fully inflated when it is called. It makes accessing those objects incredibly simple because they already exist and function just like a normal object. The downside is that a lot of useless information might be retrieved simply because a node was touched only to obtain one small piece of information.
2) The second method is to inflate the properties of a node on demand. Instead of accessing $this->property, a call would be made like so: $prop = $this->getproperty(‘foo’); The "foo" property would then be loaded and could be accessed normally. Since, in many cases, the theme/template will be the only part of the system that knows which properties will be used and which ones will not, this code will most likely appear in the templates, which looks cluttered and is difficult to understand. The benefit to this method is that the properties are only inflated upon demand. The downside is the additional clutter in the templates.
3) The final method is to obtain a list of the available properties and create empty property objects for each one. Inside of the property is an "active" flag. When a property object is accessed, its "active" flag will be checked. If the property is not "active" then the data will be retrieved then, that single property will be inflated, and the "active" flag will be set so the object knows that future accesses don’t need to retrieve the data. The benefit of this method is that the properties are only loaded on demand (like the benefit of option 2) and yet are still "real" objects (like the benefit of option 1) that are simple to access even in templates. So this is the best of both worlds, but there is a new downside. Because these data objects now have to have some way of retrieving their own data, they will require access to the NodeFactory (which requires the DataDataStore) from within themselves. This makes the Object more complicated, with more dependencies.
I think option 3 sounds the best. I just hate to introduce layers of tight binding and complication that don’t need to be there.
Advice? Comments? Suggestions?
Inklog: new direction
After giving the code, individually, to many of the people who showed interest in Inklog I received no helpful or critical comments in regard to how it was written, how it works, or the overall design goal of the application. So I decided to release publicly. And still I received no comments, helpful, critical or otherwise, regarding it’s operation. Additionally, only a small handful of people wandered to the test site, and most of them simply tried to "hack" it into misbehaving as opposed to looking at it for what it did. And none of them bothered to let me know what they thought.
But that’s okay. I only expected as much. But that leaves me in a difficult place. Without feedback, the only direction I can proceed in is the one in my head. Without input from others, I can’t make the application suit the needs of more people. So, Inklog will proceed, but with less emphasis on the "user" and more emphasis on the "developer". This is software that I need to make my life easier and make my job easier. I figured that I should try to cater to the needs and wishes of others to ensure a strong user base, and, in the end, more modules, more functionality, and more developers. But, without others willing to even comment, I certainly can’t cater to their needs.
So, Inklog will proceed my way. Updates on its progress will occur only if I should feel the need to vent or rave about it. And when the release comes, it will do everything I want but have very little of the fluff that other users might desire. For instance: I had planned on writing an admin console module to allow users to more easily access and understand all of the features available. But I know all of the features available, so I have no real need for such a console. So, that will be put on hold. I also have no need for a simple theme installer that would allow users to easily change the look and feel of their site without having to know HTML by simply installing a pre-written theme and configuring a few options within it. I know HTML and any theme that could be pre-written isn’t going to be the theme that I want since my tastes are specific to me and I know how to build them. So I don’t really need this option. I had planned on having an installer module available that made it easy for users to upgrade existing modules and install new modules without having to download code or access their system shell. But, installing modules is easy for me, so I’m not going to waste my time building this feature.
So, in a nutshell, Inklog is still moving. But, unless a particular feature is asked for by a truly interested party, if I don’t need it, I’m not going to bother coding it.
I’m not upset. I actually kind of assumed this would happen. The code is too complicated and the GUI isn’t (yet) flashy enough for pseudo-developers to understand it or desire to understand it. And I don’t have enough real-developers reading my weblog. I’ve always had this problem, really. I’ve always been surrounded, in one way with another, with very intelligent and interesting people (and a handful of ignorant and/or boring people as well). However, never have these people taken interest in the things that I find important or interesting. I’m not sure why. Maybe they aren’t intelligent enough to understand me. Maybe I don’t explain myself well enough to allow them to understand. Maybe they are so busy with what interests them that they don’t have the time or desire to have a conversation about something new or different from their conventional line of thought. But, regardless, I’ve rarely had anyone near me that could hold a real conversation about something that really interests me.
There are a few exceptions.
With programming and software, Matt is an exception. He understands what I’m talking about and he’s willing to talk about it with me. And I think Mike T. would be as well if he and I ever had time to just sit around and talk.
With photography I know several people who can almost understand. They’re still learning and, when I see something I can teach them, I try to do my best. And Tony understands photography very well. But we have different philosophies behind the photography (his being the more commercial aspects of it, while mine are more amateur/enthusiast/artistic).
I all but stopped writing poetry, having no one to really share with. I used to have a friend named Kelly, who really understood. We’d spend a lot of time reading poems to one another and talking about what made them good and what made them bad and which ones from other people we really liked. I used to have a friend named Emily that was the same way. In fact, I think that, somewhere, in a box, I still have a poem she wrote for me, covered in coffee stains from the night we spilled our drinks on it, too drunk to control our hands.
With guitar and music in general, I have several "mentors" I can talk to. Several people in my life who really understand how it works, how to play, and what it all means in the end. However, that’s not the same. Because my level of ability is no where near where they are at. Any conversation we might have would be a request for help from me. Some day, when I put enough effort into really learning how to play, I might be able to discuss something deeper with them and, in that, learn from each other.
I could go on, but it would be pointless. The gist of what I’m trying to say is this: I’m used to learning on my own, and growing on my own, and doing things on my own. Why should this be any different?
Inklog: and god said…
… let there be code. And there was. But it sucked.
Okay, maybe it doesn’t suck. Regardless, it creates things now. And that’s it. Heh.
So, I’m getting sick of looking at all of this code and not really knowing if I’m going about it the right way. So I’m releasing version 0.0000000001a of Inklog. Wooo.
It does nothing useful. Really. So don’t get all excited and get ready to convert your blog over just yet. However, it does actually do SOMETHING, so if you’re technically inclined, give it a download.
This version of the code is licensed only one way: "You can look and run but you cannot distribute or modify". Like I’ve said before, in the end, most of this will be GPL. But, for the time being, it isn’t. Also, you are not permitted to link directly to the test site, the CVS repository or the Tarball. If you’d like to link to help get the word out, please link to this blog entry. All of these systems and URLs are in a state of flux, and I hate broken links. So please adhere to this small request.
Anonymous CVS scares the hell out of me, because I don’t really know how to get CVS to do what I want and it all seems like a giant hack anyway. So, there is no anonymous CVS. However, you CAN browse the repository. Additionally, since the code is changing so quickly, it’s difficult for me to make a Tarball. However, you can access a current Tarball via the web repository.
So, you’ve downloaded it… what do you do with it? Well, I’ll tell you.
First you’ll need a PHP enabled webserver with PEAR::DB and a MySQL database server. Go get it, I’ll wait. Now you need to get the Smarty release and untar it somewhere on your system.
Okay, now, untar the Tarball into any directory in your webroot. It doesn’t matter where but I suggest using a location that doesn’t have anything else in it, so you can easily delete it when you’re done.
Once untarred, you’ll see a directory called "db". Inside "db" is a file called "mysql.sql". You need to run that against your database. First create a database. Then create a user (or use an existing one). Then type "mysql -u username -p databasename < mysql.sql". It’ll ask for your password. Type it in.
Next copy "config.php-dist" to "config.php" in the directory you untarred in. Then edit "config.php". You just need to change the top two items: "nodepath" and "dsn". "nodepath" should point to the directory you untarred everything in and "dns" should reflect the settings you established for your MySQL database. Save this file.
Now edit "dispatch.php". Set the top three items. The first, "configpath" should point to the directory you untarred in. The second, "addllibpath", should point to the "libs" directory inside of the Smarty install you did. The third, "nodepath", should once again point to the directory you untarred Inklog in. (I know that’s silly to do it twice. Shut up. This is SUPER-ALPHA code.)
Good. Now, type "mkdir templates_c; chmod 777 templates_c" in the directory you untarred Inklog in.
Now, open your web browser and browse to the "dispatch.php" file in the untarred directory. If everything went right, you should see a page called "Main Container CONTAINER". Under it there is a link to "Create PAGE here". Click on it. Type in some stuff on the next screen keeping in mind that "locname" shouldn’t be anything more than letters and numbers (no, I don’t do any error checking yet). Press Submit.
Now browse back to "dispatch.php". You should see your new item listed. Click on it. You should see it displayed.
That’s it.
If you don’t want to go through all of that trouble, you can access the test site I set up. Basically, (test site taken offline) I followed my own instructions, step-by-step to make sure they were correct. Aside from the fact that some people may have added a few things to the database… it should function exactly as it would if it were on your own system.
Enjoy. Heh. Please remember that it’s way super-duper-alpha. It probably opens 14 security holes on your system and renders your webserver as useful as a Windows box.
Comments and suggestions are ALWAYS appreciated.
Inklog: theming
The hardest most dreadful part of Inklog is upon me: theming. I’ve got the majority of the theming code done. But every half hour that I work on it, I change it to an entirely different structure. I’m stuck in a hole in between flexibility and ease of use.
For instance, when writing the image gallery code, do I want to force users to use gallery?page=4 to signify the 4th page? Or do I want to allow them to use that or gallery/4 to signify the 4th page? What if the user speaks Spanish and she prefers gallery?pagina=4? I can allow just one option very easily. However, a very picky user will complain, and, perhaps, alter the code to do it her way. However, once the code is altered in this fashion, I’ll be reluctant to take any patches or code modification from them because they’ll be using a different starting code base than the "official" code is. Perhaps I should allow the page identifier to be specified in the configuration? This way a user can say "my page parameter is named ‘pagina’, while another user might use ‘page’, while another user might use something entirely different. I can give this level of flexibility, it just means a lot more work. I can also skip all the extra work by placing the role of deciphering which page to display on the template itself. This makes the template code more complicated but much more flexible.
If everything is stored in configuration, then the next and previous page URLs can be generated for the template instead of forcing the user to piece them together herself in the template code. One big problem with generating URLs for the template is that the URLs will be specific to a transport type (HTTP, for example). The "URL" to transport that item via XML-RPC or via SMTP might look entirely different and, at that point in the code base, the renderer doesn’t know what medium it’s being rendered for, and it shouldn’t have to. I could use an "internal" URL to the document and then have the template author run the URL through the modifier of their choice to produce the correct URL, but then the modifier will have to know a little something about the transport layer and its designed URLs. I had hoped that the transport layer would be simple to code and ultimately flexible allowing greater use by more people. This would complicate matters considerably.
I think that I’d like to use a combination of the above. Perhaps I’ll still hold the page identifier (and other things) in configuration, and, using this data, I can auto-determine how many items to retrieve, and where to begin based on the page identifier. However, I wont construct a nextURL or a previousURL for the template. Instead, I’ll provide the template with a nextPAGE and a prevPAGE and allow the template design to construct the URLs appropriate for the system.
I think.
It’s all too confusing. There are a million options and none of them are any more "right" or "wrong" than the others. The system is flexible enough that changing something like this after it has been written won’t be too difficult. Especially if I don’t have to retain backwards compatibility with the old way of doing it. Therefore, it might make the most sense to just pick one (perhaps the easiest to code that retains the most flexibility) and then, after beta testing take suggestions and rewrite it if needed. I think that’s what I’ll do.
Once again, however, and comments or suggestions you might have will be greatly appreciated.
Howard Dean at the Iowa Caucuses
I can’t honestly say anything about any presidential candidate aside from good ole Dubya, because I haven’t really been paying attention. However, after the Iowa Caucuses last night, Howard Dean has been getting quite a bit of press regarding the end of the speech he gave after coming in 3rd place. Most people think that his speech didn’t sound like something that should come from the mouth of the President of the USA. But I disagree. I think that young energy like this is exactly what our country needs to get into shape. Listen for yourself.
Howard Dean – Iowa Caucuses – Closing Speech – Snippet – mp3 – 103K.
does it make a difference?
Before I moved into our current apartment, I read the reviews at ApartmentRatings.com. I found a few bad reviews and a few good reviews. Of course, I figured more people will complain than speak of good experiences. Therefore, since the bad reviews weren’t horrible, it’s probably not bad at all. Man was I wrong.
So, even though there are probably others who will read my review and decide that my case is simply an isolated circumstance (which it very well may be), I’ve decided to post my review anyway. Maybe it’ll do some good.