Moxie.Build Keeps it Simple

Using a fully integrated stack, its powerful design eliminates barriers to getting things done.

One stack, one app, from one company.

 

Coding with the MOX server side scripting language is concise, well structured, and keeps your focus on the data. Use Moxie.Build in your company to pull together resources, centralize data, customize business workflows, and act as a highly accessible web portal for staff and customers alike.

Simple Demo

Just a simple form with one Ajax calculated field.

0

Although the MOX syntax pays heritage to BASIC, it includes modern features such as Try/Catch and Multiple Return Values from Functions. MOX encourages easy to understand step-by-step processing, and comes without language features that are typically abused and make code harder to maintain. Security is built right in; all user data is sanitized before the developer ever sees it.

Rem 'Flow Control: Pulls data from incoming web browser request and decides where to go
    [Pull]  Req.IsGet ajCalc
    
    If      ajCalc      :   AjaxReply   : Form.Ajax.Calc
    ElseIf  Req.IsGet   :   Form.Build
    Else                :   Form.Proc
    End If
EndRem

Method Form.Build()
    Rem 'Fetch or create our Person fields depending on if we have a valid user logged in
        If ($SessionIsBad)
            NewFields       "MemTab.Person.", "FirstName LastName"
        Else
            Try
                LoadRecord  "MemTab.Person", ($SessionUser)
                KeepFields  "MemTab.Person.", "FirstName LastName"
            Catch
                HtmlErr     "Oh my! it looks like we lost you somehow."
                Error       "Could not load logged in user"     'Sends admin notifications and exits proc
            End Try
        End If
    EndRem
    
    Rem 'Create some extra fields for the demo and customize the form
        NewFields           "Demo.", "Apples Oranges Fruit"
        
        GetFieldDefs        'Fetch db defenitions for db fields, creates blank defs for non-db fields
        
        WorkWith            "Demo.Apples#"
            Set             "Label",    "`Apples?"
            Set             "Attr",     ("`[!] 0, 1, 2, 3, 4, 5, 6, 7, 8, 9" & $I & "[Ajax] FruitCount, ?ajCalc=y")
        WorkWith            "Demo.Oranges#"
            Set             "Label",    "`Oranges?"
            Set             "Attr",     ("`[!] 0, 1, 2, 3, 4, 5, 6, 7, 8, 9" & $I & "[Ajax] FruitCount, ?ajCalc=y")
        WorkWith            "Demo.Fruit#"
            Set             "Label",    "`Total Fruit"
            Set             "Attr",     "`[R]"
        End WorkWith
        
        'Set up our Ajax destination inside of Demo.Fruit
        Set                 "Demo.Fruit", "0"
    EndRem
    
    'Put it on the page, in our FruitDemo Template Insertion Point
    HtmlForm                "FruitDemo", " Do Something", ""
End Method

Method Form.Ajax.Calc()
    [Pull]  Demo.Apples Demo.Oranges
    Html    (Demo.Apples + Demo.Oranges)
End Method

Function Form.Fruit.Total(pFirstName, pLastName, pApples, pOranges)
    If pApples == 0 : And pOranges == 0
        Return "&warning",  "Oops, it looks like you didn't select any fruit to share with us!"
    Else
        Return "&success",  ("Thank you " & pFirstName && pLastName & "," & _
                            " for sending us " & pApples & " Apples " & _
                            " and " & pOranges & " Oranges.")
    End If
End Function

Method Form.Proc()
    Rem 'Fetch our incomming form data
        [Pull]  "Request", "MemTab.Person.", "FirstName LastName"
        [Pull]  "Request", "Demo.", "Apples Oranges"
    EndRem
    
    'Call a processing Function that has four input parameters and two return values
    [New] AlertClass, UserMessage = Form.Fruit.Total FirstName, LastName, Apples, Oranges
    
    HtmlAlert   "FruitDemo", AlertClass, UserMessage    'Display Alert
    Form.Build                                          'Display Form again
End Method

For comparison only, here is an example of the same form being implemented with PHP, instead of using MOX in Moxie.Build. This source is about twice as large, and less modular, than the MOX equivalent.

//Ajax response 
if(isset($_GET['ajax'])){
    //sanitize the form fields
    $oranges = intval(filter_input(INPUT_POST | INPUT_GET, 'Oranges', FILTER_SANITIZE_SPECIAL_CHARS));
    $apples = intval(filter_input(INPUT_POST | INPUT_GET, 'Apples', FILTER_SANITIZE_SPECIAL_CHARS));
    //add them
    echo $apples + $oranges ;   

} else {
    $firstname = "";
    $lastname  = "";
    
    //normal request respond as page
    //check if user is logged in
    if($_SESSION['logged_in']){
        try {
            //connect to the database
            $db = new PDO("mysql:host=localhost;dbname=mysql", "moxiedb", "m0xi3" );
            //get firstname and lastname from the user, using a prepared statement to avoid sql injections :)
            $stmt = $dbh->prepare("SELECT firstname,lastname FROM users WHERE id= :user_id");
            $stmt->bindParam(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
            $stmt->execute();
            $result = stmt->fetchAll();
            foreach($result as $row)
            {
                $firstname = $row['firstname'];
                $lastname = $row['lastname'];   
            }
            $dbh=null;
        } catch(PDOException $e)
        {
            echo $e->getMessage();
        }
    } else {
        //otherwise use $_POST if it exists yet and sanitize the inputs we were given
        if(isset($_POST['MemTab.Person.FirstName']){
            $firstname = filter_input(INPUT_POST | INPUT_GET, 'MemTab.Person.FirstName', FILTER_SANITIZE_SPECIAL_CHARS);
        } 
        if(isset($_POST['MemTab.Person.LastName']){
            $firstname = filter_input(INPUT_POST | INPUT_GET, 'MemTab.Person.LastName', FILTER_SANITIZE_SPECIAL_CHARS)
        }
    }
    ?>
    
    
        
    //decide on the dialog to use and display their name if appropriate 
        if(isset($_POST['MemTab.Person.FirstName']) && ($_POST['Demo.Apples'] != "0" ||  $_POST['Demo.Oranges'] != "0")){ ?>
            
class="alert alert-success">Thank you if($firstname != ''){ echo ' '. $firstname; } if($lastname != ''){ echo ' '. $lastname; }?> , for sending us echo $_POST['Demo.Apples']; ?> Apples and echo $_POST['Demo.Oranges']; ?> Oranges.
} else if(isset($_POST['MemTabPersonFirstName']) && ($_POST['Demo.Apples'] == "0" || $_POST['Demo.Oranges'] == "0"){ ?>
class="alert alert-warning"> Oops, it looks like you didn't select any fruit to share with us!
} ?>
role="form" class="form-horizontal" action="" method="post">
class="form-group">
class="col-lg-8"> class="form-control" name="MemTab.Person.FirstName" id="MemTabPersonFirstName" accesskey="f" value="" type="text">
class="help-block col-lg-2">
class="form-group">
class="col-lg-8"> class="form-control" name="MemTab.Person.LastName" id="MemTabPersonLastName" accesskey="l" value="" type="text">
class="help-block col-lg-2">
class="form-group">
class="col-lg-8">
class="help-block col-lg-2">
class="form-group">
class="col-lg-8">
class="help-block col-lg-2">
class="form-group">
class="col-lg-8"> class="help-block"> id="FruitCount">6
class="help-block col-lg-2">
class="form-group">
class="col-lg-12">
} ?>

For comparison only, here is an example of the same form being implemented with Node.js, instead of using MOX in Moxie.Build. This source is about twice as large as the MOX equivalent.

/******
App.js
******/
var express = require('express');
var session = require('client-sessions');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));

//setup databse
var mongoose = require( 'mongoose' );
var Schema   = mongoose.Schema;
 
var User = new Schema({
    email        : String,
    firstname    : String,
    lastname     : String
});
 
mongoose.model( 'User', User );
mongoose.connect( 'mongodb://localhost/moxiedb' );

//sets up sessions
app.use(session({
  cookieName: 'session',
  secret: 'OAE9DHdjAVhzhJ7ksO4LY9tr8Xo458af',
  duration: 30 * 60 * 1000,
  activeDuration: 5 * 60 * 1000,
}));

//display main page
app.get('/', function(req, res){
  if (req.session && req.session.user) {
      User.findOne({ email: req.session.user.email }, function (err, user) {
         if(!user){
              res.render('index');
         } else {
            res.render('index', {
                user: user
            });
         }
      }
  } else {
      res.render('index');
}
});

//handles ajax request
app.get('/addfruit', function(req, res){
  var result = parseInt(req.query.apples) + parse(req.query.oranges);
  res.send(result);
});

//form submits to this
app.post('/submit', function(req, res){
    res.render('index', {
        firstname: req.body.firstname,
        lastname:  req.body.lastname,
        apples: req.body.apples,
        orange: req.body.oranges
    });
});

app.listen(8001);

/****
index.jade
Note: the jade templating engine automatically sanitizes variables when outputed with #{}
Markdown style HTML, automatically gets rendered by Express
****/
  body
    p Just a simple form with one Ajax calculated field.
    p
    if(firstname.length > 0 && (oranges > 0 || apples > 0)
    .alert.alert-success
      button.close(type='button', data-dismiss='alert') ×
        b Thank you #{firstname} #{lastname}, for sending us  #{apples} Apples  and  #{oranges} Oranges.
     else if(firstname.length && (oranges == 0 && apples == 0))
      .alert.alert-warning
        button.close(type='button', data-dismiss='alert') ×
        b Oops, #{firstname} #{lastname} it looks like you didn't select any fruit to share with us!
    form.form-horizontal(role='form', action='/submit', method='post')
      .form-group
        label.col-lg-2.control-label(for='MemTabPersonFirstName') First Name
        .col-lg-8
          if(user)
            input#MemTabPersonFirstName.form-control(name='firstname', accesskey='f', value='#{user.firstname}', type='text')
          else 
            input#MemTabPersonFirstName.form-control(name='firstname', accesskey='f', value='', type='text')

        span.help-block.col-lg-2
      .form-group
        label.col-lg-2.control-label(for='MemTabPersonLastName') Last Name
        .col-lg-8
          if(user)
           input#MemTabPersonLastName.form-control(name='lastname', accesskey='l', value='#{user.lastname}', type='text')
          else
            input#MemTabPersonLastName.form-control(name='lastname', accesskey='l', value='', type='text')
        span.help-block.col-lg-2
      .form-group
        label.col-lg-2.control-label(for='DemoApples') Apples?
        .col-lg-8
          select#DemoApples.form-control(name='apples', accesskey='a')
            option(value='0') 0
            option(value='1') 1
            option(value='2') 2
            option(value='3') 3
            option(value='4') 4
            option(value='5') 5
            option(value='6') 6
            option(value='7') 7
            option(value='8') 8
            option(value='9') 9
        span.help-block.col-lg-2
      .form-group
        label.col-lg-2.control-label(for='DemoOranges') Oranges?
        .col-lg-8
          select#DemoOranges.form-control(name='oranges', accesskey='o')
            option(value='0') 0
            option(value='1') 1
            option(value='2') 2
            option(value='3') 3
            option(value='4') 4
            option(value='5') 5
            option(value='6') 6
            option(value='7') 7
            option(value='8') 8
            option(value='9') 9
        span.help-block.col-lg-2
      .form-group
        label.col-lg-2.control-label(for='DemoFruit') Total Fruit
        .col-lg-8
          span.help-block
            span#FruitCount 6
        span.help-block.col-lg-2
      .form-group
        .col-lg-12
          button.btn.btn-default(type='submit', name='icogDoSomethingSubmit', accesskey='d')
            span.glyphicon.glyphicon-cog
            |                           Do Something
    p

script. 
    $('#DemoApples').select(function(){
        $.get('/addfruit', {
            Apples: $('#DemoApples').val(),
            Oranges:$('#DemoOranges').val(),
            ajax: true
        }, function(data){
            $('#FruitCount').text(data);
        }
    });

Everything you Need

Moxie.Build v4 includes a Web Server, an In-Memory Managed-Relationships Database, a clear-cut Content Management System ready to build on top of, and an Admin Interface for developers and back office staff. The MOX Server Side Scripting Language 'does so much for you' making complex tasks easy, while always providing a way to customize it. A robust security framework and baked-in E-Commerce make it easier to profit from your efforts. Moxie.Build is high performance, stable, easy to learn, easy to maintain, and has professional support and training available.

 

 


 

 

 

Your Client Side Sources are Waiting for You

Moxie.Build is all about server side scripting, and making front end development as automated as possible. These sources are built right in and managed for you. Each version of Moxie.Build comes with compatible client side sources that are integrated and tested.

Available Now

  • JQuery
  • Bootstrap
  • Bootstrap-Datepicker
  • DataTables.net
  • HandsonTable.com
  • TinyMCE

Coming Soon

  • C3JS.org

 


 

Comments on Moxie.Build

"I love how fast it is!" - Daniel

"Favorite thing: Speed" - Jordan

"Far more effective and many times simpler than Oracle" - Kerry

"All the good stuff from a CMS, but you still have very strong low-level control over dynamic content" - Alex

"It is certainly simpler to get data out of it and onto the page than other systems" - Leonard

"Its error reporting is awesome after dealing with PHP" - Jordan

"Moxie.Build elegantly sums up the world of CMS, eCom, DB, and programming" - Kerry

"Now that I've seen it in action...wow." - Sasa

 

 


 

Admin Interface Screen Snips