Show text from text file in cgi script

I am writing a cgi script to pull the contents of a .txt file in the
cgi-bin directory into the body of an html file and can’t seem to figure
it out.

eruby seems to be a solution, but I can’t tell if it’s to be used with
Rails or not and the documentation is lacking for a newbie.

Here’s what I’ve got:

#!/usr/local/bin/ruby
# SCRIPT hello_world.cgi
# CREATOR: Ryan Clark
puts "Content-type: text/html"
puts

#This line left intentionally blank

puts <<HTML
<!DOCTYPE html>
<html>
<head>
<title>Oliver Twist</title>
<style type ="text/css">
body {
background-color:#335;
color:#fff;
font-family:Helvetica,Arial,Verana,sans-serif;
font-size:12px;}
h1 {color:#c00}
</style>
</head>
<body>
<% File.open("oliver_twist.txt").each { |line| puts line } %>
</body>
</html>
HTML

Assuming that you have set your web server properly (presumably apache
with
mod_ruby?)
I think you should check the safeness level as you are trying to use
“tainted” data, in this case file content.
By default, you are not allowed to do so. So try with different safeness
level.
The following links might be helpful.

http://www.modruby.net/en/index.rbx?mode=search&word=shugo#label-17
http://ruby-doc.org/docs/ProgrammingRuby/html/taint.html

Regards,
Junegunn Choi.

Thanks for the links, but I do not set up the web server and this is for
a class.

The assignment is just to get the contents of oliver_twist.txt to show
in an html doc using a CGI script.

Here’s my site:

hills.ccsf.edu/~rclark4/oliver_twist.cgi

Justin,

Thanks! I was looking at this from the wrong angle, obviously.

Also, this is weird to me, but I’m new to this… I didn’t need the #{}.

Here’s the code:

#!/usr/local/bin/ruby

SCRIPT oliver_twist.cgi

CREATOR: Ryan Clark

puts “Content-type: text/html”
puts
oliver = File.open(“oliver_twist.txt”).each { |line| puts line }

#This line left intentionally blank

puts <<HTML

Oliver Twist body { background-color:#335; color:#fff; font-family:Helvetica,Arial,Verana,sans-serif; font-size:12px;} HTML

If I put the line #{oliver} between the body tags, it shows in the
result.

Here’s the page:

http://hills.ccsf.edu/~rclark4/oliver_twist.cgi

Is that bizarre or normal? Can anyone explain?

Ryan C. wrote in post #983261:

Here’s what I’ve got:

puts <<HTML

Oliver Twist body { background-color:#335; color:#fff; font-family:Helvetica,Arial,Verana,sans-serif; font-size:12px;} h1 {color:#c00} <% File.open("oliver_twist.txt").each { |line| puts line } %> HTML

puts inside puts is bad.

Look, what you’re doing is simply this:

puts “A very big string indeed”

The only difference is that you’ve written the string in the multiline
form, also known as a “here-doc”:

puts <<HTML
A very big string indeed
HTML

So, move your other puts outside this.

puts <<HTML
My header goes here
HTML

File.open(“oliver_twist.txt”).each { |line| puts line }

puts <<HTML
My footer goes here
HTML

As others have pointed out, if you get the contents of the file as a
value then you can insert it directly into a string. This is called
string interpolation.

puts <<HTML
My header goes here
#{File.read(“oliver_twist.txt”)}
My footer goes here
HTML

It looks like you would rather be using erb syntax, which is in any case
a much easier way to assemble a page.

It is possible to do this within a standalone cgi. However, you really
should look at Sinatra. Honestly. I promise you’ll be glad you did. For
one thing it has support for erb templates built in; for another, it
makes it easier to separate your app logic from your view generation.

Here is your CGI as a sinatra app, complete with a layout and inline
templates in a single file.


require “rubygems” # ruby 1.8.x only
require “sinatra”

get “/” do
@title = “Oliver Twist”
@content = File.read(“oliver_twist.txt”)
erb :book
end

END

@@ layout

<%= @title %> body { background-color:#335; color:#fff; font-family:Helvetica,Arial,Verana,sans-serif; font-size:12px;} h1 {color:#c00} <%= yield %>

@@ book


<%= @content %>

Do “gem install sinatra”, then just run this code from the command line
(ruby myapp.rb). It will start a webserver listening on port 4567. There
are other options for when you want to deploy the app for real.

HTH, Brian.

Brian,

Thanks for helping to clear up the interpolation problem. I appreciate
the sinatra suggestion and am definitely interested in becoming more
familiar. I just attended a talk on sinatra and am eager to learn
more. This project was part of an assignment for a programming class -
I’ll have to find out just how creative in our solutions we are allowed
to get.

Thanks again,

Ryan

On 02/22/2011 06:27 PM, Ryan C. wrote:

#!/usr/local/bin/ruby

<% File.open("oliver_twist.txt").each { |line| puts line } %> HTML [/code

You are not actually using eruby in your script, but you are trying to
use the eruby syntax, which is not needed. When you are using “here
documents,” you are just using big multiline strings, meaning you can
use string interpolation to insert the contents of the file into the
middle of the string.

For example:

x = “world”

puts <<HERE
hello #{x}
HERE

But you need to concentrate on reading the contents of the file into a
string first. Then you can insert it into the output.

http://rdoc.info/stdlib/core/1.9.2/IO.read

-Justin

I see. Well, if it has to be CGI, you can still use erb templates like
this:

#!/usr/bin/ruby -w
require “erb”

template = ERB.new(<<HTML)

<%= title %> body { background-color:#335; color:#fff; font-family:Helvetica,Arial,Verana,sans-serif; font-size:12px;} h1 {color:#c00}
<%= content %>
HTML

title = “Oliver Twist”
content = File.read(“oliver_twist.txt”)
puts template.result(binding)

Kernel#binding is some magic which gives the template

access to your local variables