Never write HTML, Javascript, or CSS again — Part 3 of n

As you’ll notice in the my website which I’m using as a test case  for The Great DSL Experiment, there’s a reCAPTCHA block on the new user registration page (http://needsandgifts.herokuapp.com/new_user).  Let’s have some fun getting that working in my Ruby DSL:

In the original website, the markup was:

<%= recaptcha_tags %>

which is just a function call that generates some HTML.

We first need to add the required gem:

gem 'recaptcha', :require => 'recaptcha/rails'

and then run “bundle install”

We also need to set up the API keys, for which instructions are here: https://github.com/ambethia/recaptcha/blob/master/README.rdoc

Since I don’t want to share my keys, the .gitignore file gets updated with:

config/initializers/recaptcha.rb

We also need to:

include Recaptcha::ClientHelper

in the Ruby code to be able to explicitly call recaptcha_tags in Ruby rather than from the ERB view (Rails obviously is doing some magic here.)

Now we can obtain the markup that needs to be embedded:

recaptcha_html = recaptcha_tags()

I want the recaptcha block on its own row, centered, which I’ll specify like this (remember I’m using Foundation Zurb):

airity1

 

 

 

and lastly, I’ll need to implement the “inject” function.  For this, I’ll also update clifton_lib (https://github.com/cliftonm/clifton_lib) to implement an HtmlFragment (derived from XmlNode and not to be found in the .NET equivalent of the XmlDocument and supporting classes) which is going to have a special case handler in XmlDocument#write_nodes.

Now, I’m not very thrilled with how this looks when you start reducing the width of the window — I did all my testing in full-screen width.  Something to explore and also to figure out why Foundation’s small-centered isn’t doing anything.

The result is:

airity2

 

 

 

 

 

 

As usual, you can view this live here.

And as usual, besides the centering bothering me, the bottom of the reCAPTCHA block looks really bad as well.  The number of small details is growing!  Probably a good time to address them next.

Posted in Airity, Ruby on Rails | Leave a comment

Never write HTML, Javascript, or CSS again — Part 2 of n

Some HTML, CSS, and Javascript DSL Examples

In this post, I want to show you how I:

  • added some CSS-DSL to make the checkbox and label look more pleasing by aligning vertically the checkbox
  • Fixed the HTML-DSL to embed links in the label’s text
  • Wrote the supporting Javascript in the DSL

First, we start with a basic DSL implementation:

valign2

This renders as:

valign

which bothers me because the checkbox seems elevated above the text.  So let’s fix that first.  I’m going to specify a style called “checkbox-valign” using the CSS DSL:

valign3

which has a very simple definition:

valign4

 

 

resulting in a more pleasing alignment of the checkbox:

valign8

Next, I want to use the DSL to embed some HTML into the label’s text so that “Privacy Policy” and “Terms and Conditions” become clickable links.  I’ll write it with a couple helper functions (instead of embedding the function directly in the string) to make it clearer:

valign5

The helper functions call return the HTML generated by passing an expression to the DSL’s inline function:

valign6

In the HtmlDsl class, the inline function is implemented as follows:

valign7

Finally, we need some Javascript (in DSL of course) to deal with clicking on the links and showing the correct text and activating the correct link in the sidebar,
leveraging some functions we’ve already written in the DSL as well.

valign9

 

 

 

 

 

 

Now, when we click on the links in the “I acknowledge…” label, we get taken to the appropriate text.

Note that the notable “problem” with this is, since these are not separate pages, pressing “Back” on the browser doesn’t take you back to the registration page.

Try it live here.  Click on the “Register” menu item in the menu bar, then click on the links “Privacy Policy” and “Terms and Conditions” in the text next to the right of the checkbox.

Posted in Airity, Ruby on Rails | Leave a comment

Never write HTML, Javascript, or CSS again — Part 1 of n

At this point I have a few things working in my quest to never write HTML, Javascript, or CSS again.  The working name for my DSL engines is “Airity”.  I’ve set up a Git repository here: https://github.com/cliftonm/airity

and decided to try out Digital Ocean’s hosting service.  So far, very impressed.  It’s wicked fast!

So, I’m going to be blogging about my work on creating the DSL’s (Ruby on Rails at the moment) to support my lofty goal.  You’ll be able to review the code updates on GitHub and actually play with the pages on the hosted site here: http://107.170.20.40:3000/#

Background TODO list:

  1. Figure out how why the menu bar is split until the page completely loads.
  2. Item #1 is probably related to this: Why do I have to specify
    = javascript_include_tag "application"

    twice in the views\layouts\application.html.slim file?

  3. Need to send to the server the current visible text area so that a page refresh re-shows that div (hiding the other text areas) and also “activates” the correct menu / sidebar.

Active TODO list:

Item #1:

At the moment, I have this code for generating the “I acknowledge…” checkbox in the Register section:

fz_dsl.row do
  fz_dsl.columns(16) do
    html_dsl.checkbox('ack', '&nbsp;&nbsp;I acknowledge that I have read the Privacy Policy and Terms and Conditions')
  end
end

and what I need to do is create clickable areas for “Privacy Policy” and “Terms and Conditions” that then shows those relevant text areas.  Keep in mind that these sections are all part of the home page, shown/hidden as determined by the menu clicks or programmatically in the generated JavaScript.

Item #2:

Wire up some functionality, which will start to deal with the back-end model automation, another goal of this process.  The registration and sign in screens are a great place to start.

Posted in Airity, Ruby on Rails | Leave a comment

XML Serialization in Ruby

I’ve published the gem “clifton_lib”, which is intended to be a library of useful things that I’ve built and frequently use myself for Ruby / Rails projects.  The functionality I’ve implemented first in this library is a very prototype XML serializer.

In version 0.0.1, I’ve implemented several XML helper classes, similar to .NET’s XmlDocument, to facilitate the creation and serialization of XML.  In this version, the support is bare bones but sufficient for what I need done.

Why do this?

All the implementations for XML support that I’ve seen in Ruby utilize the “method missing” feature, so that markup is written in a DSL manner.  For example:

doc.product = ‘Apples’

will yield something like:

<product>Apples</product>

I have several issues with this:

1. It isn’t object oriented.
2. It assumes you know the element and attribute names, which isn’t convenient when generating XML dynamically from other data sources
3. It leverages “method missing”, which affects performance and creates an internal DSL which isn’t necessary.
4. Frequently, the parameters are passed as hashes, which I find particularly evil in Ruby as they don’t document what the valid parameter-hashes are via function parameters.

Instead, I want to base XML document generation (and eventually parsing) on Microsoft’s implementation of the XmlDocument class in .NET:

http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx

This implementation:

1. Is a decent object-oriented solution for creating XML documents
2. Inherently supports dynamic XML generation
3. Isn’t DSL-ish.

Git repository is here: https://github.com/cliftonm/clifton_lib

Posted in Ruby on Rails, Software Development | Leave a comment

Ruby, Nested Yields, and Implicit Return Values

This is one of the many reasons I cringe at languages like Ruby with implicit behaviors.  Take this example:

class DoStuff
  attr_reader :accum

  def initialize
    @accum = ''
  end

  def do_a(&block)
    @accum << 'a'
    @accum << yield
  end

  def do_b(&block)
    @accum << 'b'
    @accum << yield
  end
end

def fubar
  do_stuff = DoStuff.new

  do_stuff.do_a do
    do_stuff.do_b do
      "rec\r\n"
    end
  end

  puts (do_stuff.accum)
end

fubar

Quick, tell me why the return is:

abrec
abrec

The reason is because the outer call do_stuff.do_a() has an implicit return of the result of the call to do_stuff.do_b() and so also returns “rec”.

To fix this, one must explicitly return an empty string as the return:

  do_stuff.do_a do
    do_stuff.do_b do
      "rec\r\n"
    end
    ''
  end

and now the return is:

abrec

So, beware, especially beginner programmers, of the implicit return in Ruby functions.

Compare this with a C# implementation:

public class DoStuff
{
    public string Accum {get; protected set;}

    public DoStuff()
    {
        Accum = "";
    }

    public void DoA(Func a)
    {
        Accum.Append("a");
        Accum.Append(a());
    }

    public void DoB(Func b)
    {
        Accum.Append("b");
        Accum.Append(b());
    }
}

class Program
{
    static void Main(string[] args)
    {
        DoStuff doStuff = new DoStuff();
        doStuff.DoA(() => doStuff.DoB(() => "rec\r\n"));
        Console.WriteLine(doStuff.Accum.ToString());
   }
}

We get a compiler error:

Cannot implicitly convert type ‘void’ to ‘string’

This clearly tells us we have done something wrong.

If we change the return types to strings, then it becomes obvious (hopefully) that we want to return an empty string:

public string DoA(Func a)
{
    Accum.Append("a");
    Accum.Append(a());
            
    return "";
}

public string DoB(Func b)
{
    Accum.Append("b");
    Accum.Append(b());

    return "";
}

and we get the desired behavior.

We can of course write the code the illustrate the implicit return of the Ruby code, but of course the C# code clearly illustrates this (and therefore the error of our ways):

public string DoA(Func a)
{
    Accum.Append("a");
    Accum.Append(a());
            
    return Accum.ToString();
}

public string DoB(Func b)
{
    Accum.Append("b");
    Accum.Append(b());

    return Accum.ToString();
}

And indeed, we get:

abrec
abrec

just like in my “wrong” Ruby example.

Posted in Coding Horrors, Rants, Ruby on Rails | 1 Comment

In The Limelight…

…for a week!

survey

 

Code Project survey question for the week.  :)

Posted in Uncategorized | Leave a comment

Relating Human Knowledge

Here’s a few random “talking points”:

Hypercard  (http://en.wikipedia.org/wiki/HyperCard) – an awesome app that Apple created “in the day”, letting people create their own “knowledge stacks” and how each “card” in the stack relates to other “cards.”

NIEM (http://en.wikipedia.org/wiki/National_Information_Exchange_Model), recognizing that data is persisted in unique schemata but needs to be exchanged in a common understandable way.  But rather than forcing a particular communication protocol, data exchange in NIEM is extensible by leveraging XML and XSD to essentially “define the definition.”

Semantic Structures (http://en.wikipedia.org/wiki/Semantic_technology) – “encodes meanings separately from data and content files, and separately from application code.”  OK, fine, but what we need is meaning encoded WITH data, not separate from data.

So – what am I getting at?

1. People need autonomy in how they work with data and how they want to persist data.
2. However, for people to be effective, we need a way to query and exchange information meaningfully
3. “Information” has little worth.  “Knowledge” has great worth, and one definition for knowledge, in my thinking is “information with meaning.”  Another definition might be “knowledge is the relationship of information.”

Then, we finally get to visualization technologies, such as mapping in general and metamaps in specific as a way to explore the relationships between information.  Key though, to any visualization system is that it must be “living”:

1. I need to be able to see and create the relationships that are meaningful in my context (the micro-context of my “dataset”)
2. Information and relationships need to be continually growing, in and of themselves (the macro-context of the “dataset”)

Share your thoughts!

Posted in Uncategorized | Leave a comment