Saturday, February 22, 2014

YAWS + External Modules

One of the first questions I had when setting up a YAWS page was, "How do I add more Erlang modules to the run?". The answer was more involved than I thought! A basic YAWS webpage (the simplest) is:

<html>
<body>
    <erl>
        out(A) -> "Hello World".
    </erl>
</body>
</html>

This is a simple webpage that prints out Hello World. What if you had already written some really cool erlang code that was outside of yaws? This is the code I was working on:

-module(page_properties).
-export([get_background_color/0]).

get_background_color() -> "#444444".

If you are typing this in, make sure you put it into a file called "page_properties.erl". The name of the file must match the module name! To build this example go into the erlang shell from Linux:

> erl

Then inside the shell, use the c function to compile. The result of compiling will be a "beam" file in the same directory. The beam file is the compiled output and it's what can be run.

> c(page_properties).

So c(page_properties) will look for page_properties.erl (because the name of the module matches the file name) and compile it and bring it into the shell session. So now I can do this:

> page_properties:get_background_color().

And it should return the background color you provided. Back to YAWS now- how do we get this code to be available inside of YAWS? Inside of YAWS there is only so much you can fit inside of the out(A) function. To load external modules into the yaws session open two terminal windows. Inside one, run the YAWS server interactively:

> sudo yaws -i

In the second terminal, navigate to the same directory that has the beam file you just built (or want to include). Then do the following:

yaws -- load page_properties

This will load page_properties into the running server! Surprisingly this was all it took. This is cool because if you have a running server and you don't want to take it down because it's live you can easily load in new code without skipping a beat! Now the yaws webpage can use the loaded module:

<html>
<body>
    <erl>
        out(A) -> Color = page_properties:get_background_color(),
                  string:join( [ "The color is: "
                               , Color ], "" ).
    </erl>
</body>
</html>

The Color is first set to the string provided by our external module, then we use string:join to concatenate the two strings together. You might ask why string:join can be used, yet other external modules have to be loaded manually- this is because some modules are "sticky", meaning they are always loaded during every run. 

No comments:

Post a Comment