Not celebrating the holidays does give me something: free time during break.
I've been tinkering with a whole bunch of different things leisurely during my break thus far. Before leaving, I had attended RIT's STEM Challenge hackathon (didn't end up working on a STEM game, though) and decided with my buddy Logan Mitchell that we'd try porting a MUD engine I had written some time ago in Java to Python, and make it better. It would be a good side-project to learn some things about the language.
One of the notable cool things I picked up was a nice way of generating the common "help files" for commands in the MUD, in a way that allows allowed us to document these commands at the same time. I had an idea. What if we could use the function docstring, and through reflection, generate a helpfile from it? Turns out, python can make that happen pretty easily. Inside our commands.py module...
import sys
import inspect
...
def help(args):
"""
Check the helpfiles for something.
syntax: help <subject>
subject - the subject or command which you want to check for help on
"""
...
# args is a namedtuple
helpFunctionName = args.tokens[1]
# use reflection to get a list of this module's function object
functions = inspect.getmembers(sys.modules[__name__], inspect.isfunction)
for functionName, function in functions:
if functionName == helpFunctionName:
docstring = function.__doc__
prelude = "help file for: " + args.tokens[1] + "\n"
dashline = ("-"*len(prelude))
return prelude + dashline + docstring
So, calling "help help" in our MUD will actually pull out help's docstring and have it contribute to the help file. Pretty cool stuff.
Saturday, December 24, 2011
Monday, December 12, 2011
Dorrie part II
I did some more stuff with Dorrie last week.
Beyond some aesthetics changes, I improved the usability of Dorrie through tooltips and previews. This led to a bunch of fun with the well-known jQuery Tools tooltip library. Using the library to create nice looking tooltips was pretty simple, once things got set up. It just boils down importing the library (and make sure that you import it after the general jQuery library), and setting up the function call inside the document ready clause like so:
$("match").tooltip();
This will call the default tooltip aesthetic, pulling in the text from the matched element's title field. Of course, this is the easiest scenario. Getting things just right to match the aesthetics of the site required a lot of tweaking.
On the home page of Dorrie, I list the steps that the process will take you through for creating your remix. After some feedback, I was told that these steps should have their terms defined, so this was a pretty good place to start for adding these tooltips. The code ended up looking like this:
$("#steps a[title]").tooltip({ effect: 'fade', tipClass: 'tooltipBig'});
The jQuery library allows the user to define multiple parameters for these tooltips. The most important, I found, were the effect, tipClass, and position parameters. The effect parameter defines the particular animation the tooltip uses upon popup (There are default styles, which are quite nice, but the library supports the ability to create custom animations, too). The tipClass parameter points to the css that the tooltip will use (allowing you to have multiple styles and not rely on the "tooltip" css class). Position defines the position where the tooltip will pop up.
In my fork of the Dorrie project, I added a few different styles of tooltips. Each one had their own respective bubble images that needed adjusting (all of mine derive from the free-to-use minimalist images jQuery tools provides), and positioning that needed tweaking.
One of the more interesting areas of using these tooltips is in the /packages/ step. Here, I add tooltips for package categories by pulling in the data that Dorrie uses in the backend making use of Django's Mako support:
<a href="#" title="{{cat.description}}">{{ cat.name }}</a>
These <a> tags make up categories that the jQuery accordion widget uses. The title fields are pulled in from the python backend (packages.py) data, a collection of python objects that represent categories, groups, and individual packages. This data is initialized on service startup. This data is in turn pulled in from Fedora's huge comps file that defines the packages it has. Overall, pretty nifty. Unfortunately, the way Dorrie currently pulls in the list of package groups within a category is different from the way it handles categories. Instead of bringing in a list of package groups that use the backend group model, it's just a list of strings. I'm not sure why it's done this way, and I intend to change it soon.
I also made an attempt to take control of jQuery Tools tooltip's way of embedding HTML in a tooltip so that I could create some nice tooltip image previews of the desktop environments. Using mako's loops, the html for each group was displayed, and inside of that it was easy to create a simple condition for adding in the tooltip...
{% for cat in cats %}
<h4><a href="#" title="{{cat.description}}">{{ cat.name }}</a></h4>
<div>
{% for group in cat.groups %}
<input type="checkbox" id="grp_{{ group }}" value="{{ group }}"
onClick='someOnclickFunction("{{ group }}")' />
{% ifequal cat.name "Desktop Environments" %}
Add CSS class for tooltip matching
Create HTML div for a tooltip
{% else %}
Default Behavior
{% endifequal %}
<br />
{% endfor %}
</div>
{% endfor %}
There were some problems, however. The html loaded inside the tooltip is by default the next section. This led us with two problems.
If we defined the HTML inside the loop, it would be generated multiple times - once per group - and could generate content based on the backend model, with data pulled in using mako. This would be fine, except that Mako generates the html before the jQuery library checks for the html to snag for the tooltip. This results in the first div being pulled out for the tooltip, and the rest displaying outside any tooltip. Not what we wanted. If I were to pull out the tooltip div from the loop, and create an explicit reference to it, the content would not be dynamic, as it would not have been generated within the loop.
I quickly looked for an alternative solution for a simple tooltip image preview, and stumbled across Alen Grakalic's script over at CSSGlobe, which does the trick pretty much flawless. I used his code as a base and am adjusting it to work for my solution (I have to finish and make the image position dynamic based on the page, not mouse position).
I'll be sure to post again when I get some of these things working, to detail other changes I've made.
Beyond some aesthetics changes, I improved the usability of Dorrie through tooltips and previews. This led to a bunch of fun with the well-known jQuery Tools tooltip library. Using the library to create nice looking tooltips was pretty simple, once things got set up. It just boils down importing the library (and make sure that you import it after the general jQuery library), and setting up the function call inside the document ready clause like so:
$("match").tooltip();
This will call the default tooltip aesthetic, pulling in the text from the matched element's title field. Of course, this is the easiest scenario. Getting things just right to match the aesthetics of the site required a lot of tweaking.
On the home page of Dorrie, I list the steps that the process will take you through for creating your remix. After some feedback, I was told that these steps should have their terms defined, so this was a pretty good place to start for adding these tooltips. The code ended up looking like this:
$("#steps a[title]").tooltip({ effect: 'fade', tipClass: 'tooltipBig'});
The jQuery library allows the user to define multiple parameters for these tooltips. The most important, I found, were the effect, tipClass, and position parameters. The effect parameter defines the particular animation the tooltip uses upon popup (There are default styles, which are quite nice, but the library supports the ability to create custom animations, too). The tipClass parameter points to the css that the tooltip will use (allowing you to have multiple styles and not rely on the "tooltip" css class). Position defines the position where the tooltip will pop up.
In my fork of the Dorrie project, I added a few different styles of tooltips. Each one had their own respective bubble images that needed adjusting (all of mine derive from the free-to-use minimalist images jQuery tools provides), and positioning that needed tweaking.
One of the more interesting areas of using these tooltips is in the /packages/ step. Here, I add tooltips for package categories by pulling in the data that Dorrie uses in the backend making use of Django's Mako support:
<a href="#" title="{{cat.description}}">{{ cat.name }}</a>
These <a> tags make up categories that the jQuery accordion widget uses. The title fields are pulled in from the python backend (packages.py) data, a collection of python objects that represent categories, groups, and individual packages. This data is initialized on service startup. This data is in turn pulled in from Fedora's huge comps file that defines the packages it has. Overall, pretty nifty. Unfortunately, the way Dorrie currently pulls in the list of package groups within a category is different from the way it handles categories. Instead of bringing in a list of package groups that use the backend group model, it's just a list of strings. I'm not sure why it's done this way, and I intend to change it soon.
I also made an attempt to take control of jQuery Tools tooltip's way of embedding HTML in a tooltip so that I could create some nice tooltip image previews of the desktop environments. Using mako's loops, the html for each group was displayed, and inside of that it was easy to create a simple condition for adding in the tooltip...
{% for cat in cats %}
<h4><a href="#" title="{{cat.description}}">{{ cat.name }}</a></h4>
<div>
{% for group in cat.groups %}
<input type="checkbox" id="grp_{{ group }}" value="{{ group }}"
onClick='someOnclickFunction("{{ group }}")' />
{% ifequal cat.name "Desktop Environments" %}
Add CSS class for tooltip matching
Create HTML div for a tooltip
{% else %}
Default Behavior
{% endifequal %}
<br />
{% endfor %}
</div>
{% endfor %}
There were some problems, however. The html loaded inside the tooltip is by default the next section. This led us with two problems.
If we defined the HTML inside the loop, it would be generated multiple times - once per group - and could generate content based on the backend model, with data pulled in using mako. This would be fine, except that Mako generates the html before the jQuery library checks for the html to snag for the tooltip. This results in the first div being pulled out for the tooltip, and the rest displaying outside any tooltip. Not what we wanted. If I were to pull out the tooltip div from the loop, and create an explicit reference to it, the content would not be dynamic, as it would not have been generated within the loop.
I quickly looked for an alternative solution for a simple tooltip image preview, and stumbled across Alen Grakalic's script over at CSSGlobe, which does the trick pretty much flawless. I used his code as a base and am adjusting it to work for my solution (I have to finish and make the image position dynamic based on the page, not mouse position).
I'll be sure to post again when I get some of these things working, to detail other changes I've made.
Subscribe to:
Posts (Atom)