August 23rd, 2002

hacking, nerdy

blank gallery name bugfix

I'm reposting my patch for the blank gallery name bug (assuming it is a bug), just in case it was missed last time. This patch is untested, so could someone test it, please?

Right now you can create a new gallery with no name, by using a space as a name. (It gives you an error, but it still makes the gallery.) You can also rename a gallery to blank.

the patch

Collapse )
  • brad

Core changes

Status of stuff from Mart:
  • Text properties are in.
  • New ItemRange is in.
  • GalleryPicturePage isn't in... I just merged that into PicturePage... they're so similar, I don't want style authors ignoring one. Instead, gallery & pages are null if there's no gallery. Makes sense, eh?
  • itemrange_skiplinks() got changed to ItemRange::print() ... whenever I see a function like foo_action(foo self, ...), it's just crying to be a method, not a global function.
Overall, Mart... I'm impressed... you're sending small pieces. Most refreshing. Just be sure to include docstrings on everything so I don't have to write them. Includes notes also about what layers should probably override them... layout vs. i18n.
  • brad

S2 %GET args

There will be times when it's necessary to pass arguments to S2 pages.

Sometimes, the S2 page won't give a damn about them, like the page=4 argument... the page just re-runs and its data structures already have page 4 populated in all the ranges.

But, sometimes the page will care.

Imagine a layout that's framed... the main page is the frameset. The framed documents are the same code, but run with a different arguments.

I could imagine framed IndexPages, but let's talk about a framed GalleryPage...

/brad/galler/2343434 -- frameset... big top area, small scrolling bottom area
/brad/galler/2343434?framearg=top -- "Click a picture below"
/brad/galler/2343434?framearg=bottom -- All the thumbnails

Then, clicking something in the bottom brings up a PicturePage in the large frame.

So, the question is... do we give S2 pages access to all the URL parameters, or only a restricted subset?

I'm in favor of a restricted subset... I foresee too many misuses if they had complete access.

So then, what's the subset? What do we call the arg? "framearg" is kinda lame.

And while we're at it, what are the names for the other args? I want URLs to be consistent (as much as possible) if people change styles. Obviously if the page size changes, or security of pictures change, or picture reordering happens, page=n arguments are no longer good.

Still, what do we call the page argument? "page"? "p"?
amused, happy
  • mart

core1.s2 proposals: ItemRange

I'm going over my old email to Brad about core1.s2 and I'm going to post it again here, revised to suit the current state of the core later.

First up, changes to ItemRange. Brad put my original ItemRange in core, but he renamed all of the members. I originally made it general enough that it could represent a range of anything, but at the time it was only used for Pages. It was my intention that the same class would be used to represent the navigation between different images within a gallery from the PicturePage. Here, then, is the revised ItemRange class:

class ItemRange
"Represents a range of items which optionally contain items. For example, in a thumbnail gallery 'pages' are items and 'pictures' are subitems."
  var bool all_subitems_displayed "True if the subitems in this range represent the entire set. In this case, all of the URL members are blank.";
  var int num_subitems_displayed "The number of subitems in this range.";
  var int total "The total number of items that are navigatable to.";
  var int current "The currently-active item.";
  var int from_subitem "The index of the first subitem in this range.";
  var int to_subitem "The index of the last subitem in this range.";
  var string url_next "URL for the 'next' link. Blank if non-applicable."; 
  var string url_prev "URL for the 'previous' link. Blank if non-applicable.";
  var string url_first "URL for the 'first' link. Blank if non-applicable.";
  var string url_last "URL for the 'last' link. Blank if non-applicable.";
  function builtin url_of(int n) "Returns the URL to use to link to the nth item";

The names “item” and “subitem” aren't very inspiring, but there's a good reason for using them instead of “page“ and “picture”: On a PicturePage, the images themselves become “items”. Also, in the future, we might have ranges of other things we've not thought of yet. These also make for more intuitive overall variable names: "Page $.pages.current of $" makes a lot more sense than "Page $ of $pages.pages" — too much of the word “page”!

All of the subitem stuff can be used to display text saying “Viewing pictures 5 through 15” and the boolean variable can be used to decide that maybe it's not worth printing out any links at all since none of the links actually go anywhere.

This means that we need a GalleryPicturePage class (discussed before, not implemented yet) with some extra members:

class GalleryPicturePage extends PicturePage
"Page showing a single picture selected from a gallery."
  var ItemRange pictures;
  var GalleryBasic gallery;
  function print_picture_navigation();
  function picture_location() "Returns text like 'Picture X of Y' where X is \$.pictures.current and Y is \$";

Also, we can extend GalleryPage a bit:

class GalleryPage extends Page
"Page class for a viewing a user's gallery."
  var Picture[] pictures
  "The pictures in this gallery which the remote user has access to see.";

  var Gallery gallery
  "The gallery being viewed.";

  var ItemRange pages;
  function print_page_navigation();
  function page_location() "Returns text like 'Page X of Y' where X is \$.pages.current and Y is \$";

Also, a default implementation of the skiplinks:

function itemrange_skiplinks(ItemRange range, string labeltext) {
  "<table width=\"100%\" style=\"text-align: center;\"><tr>\n";
  "<td width=\"12%\">" + linkif($*text_range_first, $range.url_first) + "</td>\n";
  "<td width=\"12%\">" + linkif($*text_range_prev, $range.url_prev) + "</td>\n";
  "<td width=\"12%\">" + linkif($*text_range_next, $range.url_next) + "</td>\n";
  "<td width=\"12%\">" + linkif($*text_range_last, $range.url_last) + "</td>\n";

Implemented as a separate function because I think in most cases styles will use common code for all of these structures, so this'll make overriding easy. $labeltext is to be passed the return value of page_location() or picture_location() from the classes that use ItemRange above.

That's all.

amused, happy
  • mart

core1.s2 proposals: Some new text properties

This one's simple enough.

property string text_range_first {
    noui = 1;
property string text_range_prev {
    noui = 1;
property string text_range_next {
    noui = 1;
property string text_range_last {
    noui = 1;
property string text_link_index {
    noui = 1;
property string text_link_gallery {
    noui = 1;
set text_range_first = "First";
set text_range_prev = "Previous";
set text_range_next = "Next";
set text_range_last = "Last";
set text_link_index = "Back to Index";
set text_link_gallery = "Back to Gallery";

A bunch of fun text properties to set the text used in the inter-item skiplinks. These have noui set on because “simple users” get overwhelmed by hundreds of options, and in most cases no layer above i18nc will change these. Layouts will probably only use these properties as ALT text for their imagey links, so users probably won't even notice the text is there.

The reason these are in the core is that almost all layouts will use them, and it makes sense therefore to only translate them once (in i18nc) rather than for each layout which uses them (in i18n).

amused, happy
  • mart

FotoBilder Journal Style

I recommend setting the journal style of the FotoBilder community to Lucent's Magazine, because it doesn't use tables and thus isn't phased by preformatted source code.

For those whose friends pages I just broke: if your friends page style can't handle large portions of preformatted source code, don't add developer-related discussion communities to your friends list. lj_dev uses a style which doesn't use tables deliberately because I anticipated code discussion. FotoBilder should be using a non-table style too.

  • mart

core1.s2 proposals: Functionize page components

Right now, all of the content for each page is mostly generated by one function: the print_body() method of the relevant Page subclass.

We need to abstract everything out into functions. For example,

function GalleryPage::printBody() {
function GalleryPage::print_page_navigation() {
  if ($.pages.alldisplayed != true) {
    itemrange_skiplinks($.pages, $this->page_location());
function GalleryPage::page_location() : string {
  return "Page $.pages.current of $";
function GalleryPage::print_gallery() {
    # ... some implementation of printing out a bunch of images

What are the benefits of this separation? Customization, primarily. Componentizing destinct parts of the output makes it far easier for the higher layers to swap bits around without having to rewrite everything. If I don't like the way my selected layout has implemented the navigation skiplinks, I can simply override itemrange_skiplinks(). If my selected layout only puts skiplinks at the bottom and I want them at the top too, I can just override GalleryPage::print_body().

Obviously the same would be done for similar distinct components on other views. IndexPage already has a distinct function for printing the gallery links, but PicturePage could do with separating the output of the image from the output of the navigation links, title, metadata and so forth. (We don't actually have titles and metadata available yet, but they should be available eventually.)

amused, happy
  • mart

Old S2 Bug Report: Printing objects directly

Well, not exactly a bug report and more of a "this sucks, please change."

When you do one of:

  • print "blah "+$somecolor;
  • print "blah $somecolor";

it turns the $somecolor reference into a call to the toString method of the Color class.

However, when you do one of:

  • print $somecolor;
  • print "$somecolor";

it moans that $somecolor isn't a string, rather than converting it.

I'd be nice if print could automatically stringify single parameters too.

I wrote this report back before I was familiar with the workings of the compiler. I could probably fix this myself now with a lot of headache and effort, but Brad will be able to fix it much more efficiently because the compiler is his baby.

It'd be nice to not have to do the ol' type conversion trick anymore. (""+$object)

amused, happy
  • mart

core1.s2 proposals: Titles defined in core, not in layouts

I think the stock layouts should not touch the title functions but instead let the core handle it. My reasoning is that titles do not have layout because they are just text, and layouts are for laying out rather than for setting text. By putting title-generation functions in core rather than in layout, translation only has to be done once. Translating pretty-much the same titles for each layout seems a bit silly. The user can already set the main “global” title with a property, and if they really care they can override the title functions in their user layer. Layouts, though, have no reason to touch titles.