Wednesday 27 March 2019

Web Tutorial: Ruby Website Template Generator

One of the many repetitive tasks of web development is setting up the main HTML file, CSS and JavaScript in the correct folder. Normally that doesn't take very long, but as with all repetitive tasks, it is best automated for minimal error.

Today, I would like to walk you through a website generator program. And for that, we'll be using Ruby. It's just one of the many little things I did to help me learn the language. What this website generator does is to create a HTML file, a CSS file and a JavaScript file. It will then insert references to the CSS and JavaScript files in the HTML file, along with the standard markup.

We begin by putting in a puts statement. Simple enough?
puts "Welcome to Teochew Thunder's Website Template Generator!"


And there it runs...


Next, we declare the variable continue and set it to an empty string.
puts "Welcome to Teochew Thunder's Website Template Generator!"

continue = ""


Then we use a While loop which will go on forever as long as continue is "Y" or "y". The bulk of your code will be in this While loop.
puts "Welcome to Teochew Thunder's Website Template Generator!"

continue = ""
begin

end while continue == "Y" or continue == "y"


Let's put in some user input. First, ask the user if he or she wishes to continue, then get the input and use the chomp method to remove spaces.
puts "Welcome to Teochew Thunder's Website Template Generator!"

continue = ""
begin
    puts "Do you wish to continue? (Y/N)"
    continue = gets.chomp
end while continue == "Y" or continue == "y"


Now when you run this code, it keeps asking you the same question as long as you enter either "Y" or "y"!


We follow up with asking a few more pertinent questions from the user. First, the site name, which is stored in the variable siteName. Then the directory name, which is... take a guess!
begin
    puts "What is this site called?"
    siteName = gets.chomp;

    puts "Please input the name of the new directory to be created."
    puts "If this is a subdirectory of another directory, the parent folder must exist."
    directoryName = gets.chomp;

    puts "Do you wish to continue? (Y/N)"
    continue = gets.chomp
end while continue == "Y" or continue == "y"


So far so good?


Here, we'll do a little test by checking if the directory pointed to by directoryName already exists. If it does, print an error message.
begin
    puts "What is this site called?"
    siteName = gets.chomp;

    puts "Please input the name of the new directory to be created."
    puts "If this is a subdirectory of another directory, the parent folder must exist."
    directoryName = gets.chomp;

    if File::directory?(directoryName)
        puts "This directory already exists."
    else

    end

    puts "Do you wish to continue? (Y/N)"
    continue = gets.chomp
end while continue == "Y" or continue == "y"


If not, use the mkdir() method of the Dir object to create the directory. And at the end of it, print a success message.
begin
    puts "What is this site called?"
    siteName = gets.chomp;

    puts "Please input the name of the new directory to be created."
    puts "If this is a subdirectory of another directory, the parent folder must exist."
    directoryName = gets.chomp;

    if File::directory?(directoryName)
        puts "This directory already exists."
    else
        Dir.mkdir(directoryName)

        puts "Site created for %s." % [siteName]
    end

    puts "Do you wish to continue? (Y/N)"
    continue = gets.chomp
end while continue == "Y" or continue == "y"


You'll see this happens. A folder is created. It's empty, but it's there. Just like my wallet. (hur hur)




But wait, what if you try this a second time? That's right, your program gives you an error message because you already created that directory.


Now, what if you try creating a subfolder in a folder that doesn't exist?

That's an excellent question, compadre, and I'm going to answer that right now. What happens is that Ruby throws an exception. But like any worthy programmer, we want to handle this exception.

We catch this exception by placing the rescue clause before the end of the While loop. Then we use ENOENT as the exception name (ENOENT pretty much stands for Error, No Entry which is the kind of exception thrown when a specified directory is not found), so if the  directory is not found, control passes on to the block after the rescue clause.
    puts "Do you wish to continue? (Y/N)"
    continue = gets.chomp

rescue Errno::ENOENT

end while continue == "Y" or continue == "y"


From here, we print an error message and resume asking if the user wants to continue.
    puts "Do you wish to continue? (Y/N)"
    continue = gets.chomp

rescue Errno::ENOENT
    puts "Error: Directory not created. The parent of the new directory '%s' was not found." % [directoryName]

    puts "Do you wish to continue? (Y/N)"
    continue = gets.chomp
end while continue == "Y" or continue == "y"


Yep, it works!


OK, we've tested and handled all possible points of failure. Now let's handle successful cases. If everything goes smoothly and the directory is created, what we want to do is create subdirectories and files within that directory. To do so, we'll use Ruby's Dir object. The chdir() method makes the program go into the directory specified. In this case, it's the newly created directory. From there, we use the mkdir() method to create the directories js, img and css within the new directory. Ever use FTP before? Pretty much the same thing!
    if File::directory?(directoryName)
        puts "This directory already exists."
    else
        Dir.mkdir(directoryName)

        Dir.chdir(directoryName)
        Dir.mkdir("js")
        Dir.mkdir("img")
        Dir.mkdir("css")

        puts "Site created for %s." % [siteName]
    end


You will need to test this by removing the webgentest directory previously created, but once you run your program again, you should see subdirectories within webgentest.


Now, we change directory to js, and inside the js folder, create a new file using the new() method of the File object. We'll call it script.js, though feel free to call it anything you like. The second argument is "w" for Write mode. It doesn't really matter at this point because...
    if File::directory?(directoryName)
        puts "This directory already exists."
    else
        Dir.mkdir(directoryName)

        Dir.chdir(directoryName)
        Dir.mkdir("js")
        Dir.mkdir("img")
        Dir.mkdir("css")

        Dir.chdir("js")
        jsFile = File.new("script.js", "w")

        puts "Site created for %s." % [siteName]
    end


...our next step is to close that file. Yep, we're not writing anything in it. It's blank. Now that this is done, use the chdir() method to move back to the webgentest directory.
    if File::directory?(directoryName)
        puts "This directory already exists."
    else
        Dir.mkdir(directoryName)

        Dir.chdir(directoryName)
        Dir.mkdir("js")
        Dir.mkdir("img")
        Dir.mkdir("css")

        Dir.chdir("js")
        jsFile = File.new("script.js", "w")
        jsFile.close
        Dir.chdir("../")   

        puts "Site created for %s." % [siteName]
    end


Do the same for the css subdirectory.
    if File::directory?(directoryName)
        puts "This directory already exists."
    else
        Dir.mkdir(directoryName)

        Dir.chdir(directoryName)
        Dir.mkdir("js")
        Dir.mkdir("img")
        Dir.mkdir("css")

        Dir.chdir("js")
        jsFile = File.new("script.js", "w")
        jsFile.close
        Dir.chdir("../")   
   
        Dir.chdir("css")
        cssFile = File.new("styles.css", "w")
        cssFile.close
        Dir.chdir("../")

        puts "Site created for %s." % [siteName]
    end


To test this, delete the webgentest directory and run your program again. Now in the js and css subdirectories, you should see the files you created.


Now, in the main directory, which is webgentest, we start creating the index file. This will be called index.html, and this time, we use Write mode for an actual reason.
        Dir.chdir("js")
        jsFile = File.new("script.js", "w")
        jsFile.close
        Dir.chdir("../")   
   
        Dir.chdir("css")
        cssFile = File.new("styles.css", "w")
        cssFile.close
        Dir.chdir("../")       

        indexFile = File.new("index.html", "w")
        indexFile.close

        puts "Site created for %s." % [siteName]


We'll use the syswrite() method to start writing lines within index.html. This is where we get to use siteName which we defined earlier as the title. script.js and styles.css are referenced in the head tag.
        Dir.chdir("js")
        jsFile = File.new("script.js", "w")
        jsFile.close
        Dir.chdir("../")   
   
        Dir.chdir("css")
        cssFile = File.new("styles.css", "w")
        cssFile.close
        Dir.chdir("../")       

        indexFile = File.new("index.html", "w")
        indexFile.syswrite("<!DOCTYPE html>\n")
        indexFile.syswrite("<html>\n")
        indexFile.syswrite("    <head>\n")
        indexFile.syswrite("        <title>" + siteName + "</title>\n")
        indexFile.syswrite("        <script src=\"js/script.js\"></script>\n")
        indexFile.syswrite("        <link rel=\"stylesheet\" type=\"text/css\" href=\"css/styles.css\">\n")
        indexFile.syswrite("    </head>\n")
        indexFile.syswrite("\n")
        indexFile.syswrite("    <body>\n")
        indexFile.syswrite("        <!-- Your content here -->\n")
        indexFile.syswrite("    </body>\n")
        indexFile.syswrite("</html>\n")
        indexFile.close

        puts "Site created for %s." % [siteName]


Time to test! Delete the webgentest directory one last time, then run your program. Now you should have index.html in your main directory.


And index.html will have this written in it!


Possible modifications

Now that we've done all this, you could modify this little generator to do things how you like them. Maybe you don't like the naming convention? Change it! Perhaps you'd like more stuff in your index.html file? Or maybe you don't even want an index.html file, but prefer index.php or index.asp? All doable. Sky's the limit, yo.

Ruby's a nice little language for the little pleasures in life. Of course, it's capable of far more powerful stuff, but this is a great start!

Thank you for reading. It's been a genuine pleasure!
T___T

No comments:

Post a Comment