SlideShare a Scribd company logo
go-start
A high level web-framework for Go
Goals
• Create a high level web-framework for Go,
  like Django for Python or Rails for Ruby
• Be Go-ish
• Don’t make stuff more complicated than it
  has to be
• Convention over configuration
• Easy setup and deployment
Current status

• In development for 10 months
• Work sponsored by STARTeurope
• Used in production for http://startuplive.in
• Go v1.0
What’s in it?

• MVC
• Prefer Go syntax to template languages
• HTML5 Boilerplate out of the box
• MongoDB
• All batteries included
All batteries included

• HTML5 Boilerplate
• jQuery
• External dependencies fetched
  automatically:
  go get -u github.com/ungerik/go-start
Views
Philosophy

• Why learn another template language if you
  can use Go syntax?
• DOM tree has a 1:1 Go object
  representation on the server
• Every element has an ID to enable sync of
  DOM tree and server view representation
Higher level abstractions
• view.List      • view.Menu
• view.Table     • view.Video
• view.Form      • view.Page
• view.ModelView
• view.If
HTML Tags / Shortcuts
• H1, H2, ...   • Br
•P              • B, I, Q
• Pre           • Em, Strong
• A, A_blank    • Ul, Ol
• Img
So how does a view look
         like?
view := Views{
! NewDiv("myclass",
! ! H1("Example HTML structure"),
! ! P("This is a paragraph"),
! ! P(
! ! ! HTML("Some unescaped HTML:<br/>"),
! ! ! Printf("The number of the beast: %d", 666),
! ! ! Escape("Will be escaped: 666 < 999"),
! ! ),
! ! A_blank("http://go-lang.org", "A very simple link"),
! ),
! Hr(),
! Pre("! <- pre formated text, followed by a list:"),
! Ul("red", "green", "blue"),
! &Template{
! ! Filename:     "mytemplate.html",
! ! GetContext: func(ctx *Context) (interface{}, error) {
! ! ! return map[string]string{"Key": "Value"}, nil
! ! },
! },
}
Yes, templates are
    supported
But I ended up using them
   only for the HTML5
Boilerplate Page template
Dynamic Views
view := NewDynamicView(
!   func(context *Context) (view View, err error) {
!   !    var names []string
!   !    i := models.Users.Sort("Name.First").Sort("Name.Last").Iterator();
!   !    for doc := i.Next(); doc != nil; doc = i.Next() {
!   !    !   names = append(names, doc.(*models.User).Name.String())
!   !    }
!   !    if i.Err() != nil {
!   !    !   return nil, i.Err()
!   !    }! !     !
!   !    return &List{!   // List = higher level abstraction, Ul() = shortcut
!   !    !   Class: "my-ol",
!   !    !   Ordered: true,
!   !    !   Model: EscapeStringsListModel(names),
!   !    }, nil
!   },
)
view := &ModelView{
!   GetModelIterator: func(context *Context) model.Iterator {
!   !    return models.Users.Sort("Name.First").Sort("Name.Last").Iterator()
!   },
!   GetModelView: func(model interface{}, context *Context) (view View, err error) {
!   !    user := model.(*models.User)
!   !    return PrintfEscape("%s, ", user.Name), nil
!   },
}
HTML Pages
Homepage := &Page{
!   OnPreRender: func(page *Page, context *Context) (err error) {
!   !    context.Data = &PerPageData{...} // Set global page data at request context
!   },
!   WriteTitle: func(context *Context, writer io.Writer) (err error) {
!   !    writer.Write([]byte(context.Data.(*PerPageData).DynamicTitle))
!   !    return nil
!   },
!   CSS:           HomepageCSS,
!   WriteHeader: RSS("go-start.org RSS Feed", &RssFeed)
!   WriteScripts: PageWriters(
!   !    Config.Page.DefaultWriteScripts,
!   !    JQuery,   // jQuery/UI is built-in
!   !    JQueryUI,
!   !    JQueryUIAutocompleteFromURL(".select-username", IndirectURL(&API_Usernames), 2),
!   !    GoogleAnalytics(GoogleAnalyticsID), // Google Analytics is built-in
!   )
!   Content: Views{},
}
URL structure
Admin_Auth := NewBasicAuth("go-start.org", "admin", "password123")


func Paths() *ViewPath {
!   return &ViewPath{View: Homepage, Sub: []ViewPath{                      // /
!   !    {Name: "style.css", View: HomepageCSS},                           // /style.css
!   !    {Name: "feed", View: RssFeed},                                    // /feed/
!   !    {Name: "admin", View: Admin, Auth: Admin_Auth, Sub:   []ViewPath{ // /admin/
!   !    !   {Name: "user", Args: 1, View: Admin_User, Auth:   Admin_Auth},// /admin/user/<ID>/
!   !    }},
!   !    {Name: "api", Sub: []ViewPath{                   //   404 because no view defined
!   !    !   {Name: "users.json", View: API_Usernames},   //   /api/users.json
!   !    }},
!   }
}
Running the server
view.Init("go-start.org", CookieSecret, "pkg/myproject", "pkg/
gostart")

view.Config.RedirectSubdomains = []string{"www"}
view.Config.Page.DefaultMetaViewport = "width=960px"

view.RunConfigFile(Paths(), "run.config")
Models
Models
• Models are Go structs
  (marshaling via reflection)
• Meta information for validation and display
  is added via tags
• Forms and DB share the same model and
  validation mechanism
• MongoDB is the default database
FormModel
type SignupFormModel struct {
!   Email     model.Email     `gostart:"required"`
!   Password1 model.Password `gostart:"required|label=Password|minlen=6"`
!   Password2 model.Password `gostart:"label=Repeat password"`
}

func (self *SignupFormModel) Validate(metaData model.MetaData) []*model.ValidationError {
!   if self.Password1 != self.Password2 {
!   !    return model.NewValidationErrors(os.NewError("Passwords don't match"), metaData)
!   }
!   return model.NoValidationErrors
}



form := &Form{
!   ButtonText: "Signup",
!   FormID:      "user_signup",
!   GetModel: func(form *Form, context *Context) (interface{}, error) {
!   !    return &SignupFormModel{}, nil
!   },
!   OnSubmit: func(form *Form, formModel interface{}, context *Context) (err error) {
!   !    m := formModel.(*SignupFormModel)
!   !    // ... create user in db and send confirmation email ...
!   !    return err
!   },
}
mongo.Document
type ExampleDoc struct {
!   mongo.DocumentBase `bson:",inline"`                  // Give it a Mongo ID
!   Person              mongo.Ref `gostart:"to=people"` // Mongo ID ref to a document in
"people" collection
!   LongerText          model.Text `gostart:"rows=5|cols=80|maxlen=400"`
!   Integer             model.Int `gostart:"min=1|max=100"`
!   Email               model.Email    // Normalization + special treament in forms
!   PhoneNumber         model.Phone    // Normalization + special treament in forms
!   Password            model.Password // Hashed + special treament in forms
!   SubDoc              struct {
!   !    Day       model.Date
!   !    RealFloat model.Float    `gostart:"valid"
!   !    Drinks    []mongo.Choice `gostart:"options=Beer,Wine,Water"`
!   }
}
mongo.Collection
var ExampleDocs *mongo.Collection = mongo.NewCollection("exampledocs", (*ExampleDoc)(nil))
mongo.Query
i := models.Users.Filter("Name.Last", "Smith").Sort("Name.First").Iterator();

for doc := i.Next(); doc != nil; doc = i.Next() {
!   user := doc.(*models.User)
!   // ...
}

// Err() returns any error after Next() returned nil:
if i.Err() != nil {
!   panic(i.Err())
}
Create, modify, save a
 mongo.Document
user := models.Users.NewDocument().(*models.User)

user.Name.First.Set("Erik")
user.Name.Last.Set("Unger")

doc, err := models.Groups.Filter(“Name”, “testgroup”).One()
group := doc.(*models.Group)
user.Group.Set(group) // sets a mongo.Ref to the group
!
err := user.Save()
Additional packages
• Email (message creation missing in standard
  mail package + Google Mail defaults)
• Gravatar
• RSS parsing
• Amiando event management
  (used by http://startuplive.in)
Where to get it


• go get -u github.com/ungerik/go-start
• Documentation: http://go-start.org/
One more thing ;-)
We are hiring!
    STARTeurope
Go+Javascript Pioneers
         (Vienna)
The End
          Questions?

• erik.unger@starteurope.at
• Twitter: @ungerik
• Skype: ungerik

More Related Content

What's hot

A Short Introduction To jQuery
A Short Introduction To jQueryA Short Introduction To jQuery
A Short Introduction To jQuery
Sudar Muthu
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
Laurence Svekis ✔
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
Pamela Fox
 
Interacting with the DOM (JavaScript)
Interacting with the DOM (JavaScript)Interacting with the DOM (JavaScript)
Interacting with the DOM (JavaScript)
Florence Davis
 
jQuery Features to Avoid
jQuery Features to AvoidjQuery Features to Avoid
jQuery Features to Avoid
dmethvin
 
jQuery Presentation
jQuery PresentationjQuery Presentation
jQuery Presentation
Rod Johnson
 
Getting Started with DOM
Getting Started with DOMGetting Started with DOM
Getting Started with DOM
Hernan Mammana
 
Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0
Jeremy Gillick
 
Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...
Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...
Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...
Nagios
 
Javascript: Ajax & DOM Manipulation v1.2
Javascript: Ajax & DOM Manipulation v1.2Javascript: Ajax & DOM Manipulation v1.2
Javascript: Ajax & DOM Manipulation v1.2
borkweb
 
Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64
Alfresco Software
 
Selenium再入門
Selenium再入門Selenium再入門
Selenium再入門
Norio Suzuki
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4
Heather Rock
 
Joomla! Template for Beginners
Joomla! Template for BeginnersJoomla! Template for Beginners
Joomla! Template for Beginners
Slashes & Dots Sdn Bhd
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
KyeongMook "Kay" Cha
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJSAaronius
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
EPAM Systems
 

What's hot (20)

A Short Introduction To jQuery
A Short Introduction To jQueryA Short Introduction To jQuery
A Short Introduction To jQuery
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
Interacting with the DOM (JavaScript)
Interacting with the DOM (JavaScript)Interacting with the DOM (JavaScript)
Interacting with the DOM (JavaScript)
 
jQuery Features to Avoid
jQuery Features to AvoidjQuery Features to Avoid
jQuery Features to Avoid
 
jQuery Presentation
jQuery PresentationjQuery Presentation
jQuery Presentation
 
Getting Started with DOM
Getting Started with DOMGetting Started with DOM
Getting Started with DOM
 
Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0
 
Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...
Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...
Nagios Conference 2014 - Troy Lea - JavaScript and jQuery - Nagios XI Tips, T...
 
Javascript: Ajax & DOM Manipulation v1.2
Javascript: Ajax & DOM Manipulation v1.2Javascript: Ajax & DOM Manipulation v1.2
Javascript: Ajax & DOM Manipulation v1.2
 
Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64
 
Jquery ui
Jquery uiJquery ui
Jquery ui
 
Error found
Error foundError found
Error found
 
Selenium再入門
Selenium再入門Selenium再入門
Selenium再入門
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4
 
Joomla! Template for Beginners
Joomla! Template for BeginnersJoomla! Template for Beginners
Joomla! Template for Beginners
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 

Similar to The go-start webframework (GTUG Vienna 27.03.2012)

Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
fakedarren
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
Jussi Pohjolainen
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajaxbaygross
 
Replacing Oracle with MongoDB for a templating application at the Bavarian go...
Replacing Oracle with MongoDB for a templating application at the Bavarian go...Replacing Oracle with MongoDB for a templating application at the Bavarian go...
Replacing Oracle with MongoDB for a templating application at the Bavarian go...
Comsysto Reply GmbH
 
MongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in BavariaMongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
postrational
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
Joaquim Rocha
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
DEVCON
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
Azure F#unctions
Azure F#unctionsAzure F#unctions
Azure F#unctions
☁️ Mikhail Shilkov
 
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridasFrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
Loiane Groner
 
The Django Web Application Framework
The Django Web Application FrameworkThe Django Web Application Framework
The Django Web Application Framework
Simon Willison
 
Summit2014 topic 0066 - 10 enhancements that require 10 lines of code
Summit2014 topic 0066 - 10 enhancements that require 10 lines of codeSummit2014 topic 0066 - 10 enhancements that require 10 lines of code
Summit2014 topic 0066 - 10 enhancements that require 10 lines of code
Angel Borroy López
 
Django Girls Mbale [victor's sessions]
Django Girls Mbale [victor's sessions]Django Girls Mbale [victor's sessions]
Django Girls Mbale [victor's sessions]
Victor Miclovich
 
Practical HTML5: Using It Today
Practical HTML5: Using It TodayPractical HTML5: Using It Today
Practical HTML5: Using It Today
Doris Chen
 

Similar to The go-start webframework (GTUG Vienna 27.03.2012) (20)

Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 
Jquery fundamentals
Jquery fundamentalsJquery fundamentals
Jquery fundamentals
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajax
 
Replacing Oracle with MongoDB for a templating application at the Bavarian go...
Replacing Oracle with MongoDB for a templating application at the Bavarian go...Replacing Oracle with MongoDB for a templating application at the Bavarian go...
Replacing Oracle with MongoDB for a templating application at the Bavarian go...
 
MongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in BavariaMongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in Bavaria
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
Azure F#unctions
Azure F#unctionsAzure F#unctions
Azure F#unctions
 
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridasFrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
 
The Django Web Application Framework
The Django Web Application FrameworkThe Django Web Application Framework
The Django Web Application Framework
 
Summit2014 topic 0066 - 10 enhancements that require 10 lines of code
Summit2014 topic 0066 - 10 enhancements that require 10 lines of codeSummit2014 topic 0066 - 10 enhancements that require 10 lines of code
Summit2014 topic 0066 - 10 enhancements that require 10 lines of code
 
Django Girls Mbale [victor's sessions]
Django Girls Mbale [victor's sessions]Django Girls Mbale [victor's sessions]
Django Girls Mbale [victor's sessions]
 
Practical HTML5: Using It Today
Practical HTML5: Using It TodayPractical HTML5: Using It Today
Practical HTML5: Using It Today
 

Recently uploaded

Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 

Recently uploaded (20)

Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 

The go-start webframework (GTUG Vienna 27.03.2012)

  • 1. go-start A high level web-framework for Go
  • 2. Goals • Create a high level web-framework for Go, like Django for Python or Rails for Ruby • Be Go-ish • Don’t make stuff more complicated than it has to be • Convention over configuration • Easy setup and deployment
  • 3. Current status • In development for 10 months • Work sponsored by STARTeurope • Used in production for http://startuplive.in • Go v1.0
  • 4. What’s in it? • MVC • Prefer Go syntax to template languages • HTML5 Boilerplate out of the box • MongoDB • All batteries included
  • 5. All batteries included • HTML5 Boilerplate • jQuery • External dependencies fetched automatically: go get -u github.com/ungerik/go-start
  • 7. Philosophy • Why learn another template language if you can use Go syntax? • DOM tree has a 1:1 Go object representation on the server • Every element has an ID to enable sync of DOM tree and server view representation
  • 8. Higher level abstractions • view.List • view.Menu • view.Table • view.Video • view.Form • view.Page • view.ModelView • view.If
  • 9. HTML Tags / Shortcuts • H1, H2, ... • Br •P • B, I, Q • Pre • Em, Strong • A, A_blank • Ul, Ol • Img
  • 10. So how does a view look like?
  • 11. view := Views{ ! NewDiv("myclass", ! ! H1("Example HTML structure"), ! ! P("This is a paragraph"), ! ! P( ! ! ! HTML("Some unescaped HTML:<br/>"), ! ! ! Printf("The number of the beast: %d", 666), ! ! ! Escape("Will be escaped: 666 < 999"), ! ! ), ! ! A_blank("http://go-lang.org", "A very simple link"), ! ), ! Hr(), ! Pre("! <- pre formated text, followed by a list:"), ! Ul("red", "green", "blue"), ! &Template{ ! ! Filename: "mytemplate.html", ! ! GetContext: func(ctx *Context) (interface{}, error) { ! ! ! return map[string]string{"Key": "Value"}, nil ! ! }, ! }, }
  • 12. Yes, templates are supported
  • 13. But I ended up using them only for the HTML5 Boilerplate Page template
  • 15. view := NewDynamicView( ! func(context *Context) (view View, err error) { ! ! var names []string ! ! i := models.Users.Sort("Name.First").Sort("Name.Last").Iterator(); ! ! for doc := i.Next(); doc != nil; doc = i.Next() { ! ! ! names = append(names, doc.(*models.User).Name.String()) ! ! } ! ! if i.Err() != nil { ! ! ! return nil, i.Err() ! ! }! ! ! ! ! return &List{! // List = higher level abstraction, Ul() = shortcut ! ! ! Class: "my-ol", ! ! ! Ordered: true, ! ! ! Model: EscapeStringsListModel(names), ! ! }, nil ! }, )
  • 16. view := &ModelView{ ! GetModelIterator: func(context *Context) model.Iterator { ! ! return models.Users.Sort("Name.First").Sort("Name.Last").Iterator() ! }, ! GetModelView: func(model interface{}, context *Context) (view View, err error) { ! ! user := model.(*models.User) ! ! return PrintfEscape("%s, ", user.Name), nil ! }, }
  • 18. Homepage := &Page{ ! OnPreRender: func(page *Page, context *Context) (err error) { ! ! context.Data = &PerPageData{...} // Set global page data at request context ! }, ! WriteTitle: func(context *Context, writer io.Writer) (err error) { ! ! writer.Write([]byte(context.Data.(*PerPageData).DynamicTitle)) ! ! return nil ! }, ! CSS: HomepageCSS, ! WriteHeader: RSS("go-start.org RSS Feed", &RssFeed) ! WriteScripts: PageWriters( ! ! Config.Page.DefaultWriteScripts, ! ! JQuery, // jQuery/UI is built-in ! ! JQueryUI, ! ! JQueryUIAutocompleteFromURL(".select-username", IndirectURL(&API_Usernames), 2), ! ! GoogleAnalytics(GoogleAnalyticsID), // Google Analytics is built-in ! ) ! Content: Views{}, }
  • 20. Admin_Auth := NewBasicAuth("go-start.org", "admin", "password123") func Paths() *ViewPath { ! return &ViewPath{View: Homepage, Sub: []ViewPath{ // / ! ! {Name: "style.css", View: HomepageCSS}, // /style.css ! ! {Name: "feed", View: RssFeed}, // /feed/ ! ! {Name: "admin", View: Admin, Auth: Admin_Auth, Sub: []ViewPath{ // /admin/ ! ! ! {Name: "user", Args: 1, View: Admin_User, Auth: Admin_Auth},// /admin/user/<ID>/ ! ! }}, ! ! {Name: "api", Sub: []ViewPath{ // 404 because no view defined ! ! ! {Name: "users.json", View: API_Usernames}, // /api/users.json ! ! }}, ! } }
  • 22. view.Init("go-start.org", CookieSecret, "pkg/myproject", "pkg/ gostart") view.Config.RedirectSubdomains = []string{"www"} view.Config.Page.DefaultMetaViewport = "width=960px" view.RunConfigFile(Paths(), "run.config")
  • 24. Models • Models are Go structs (marshaling via reflection) • Meta information for validation and display is added via tags • Forms and DB share the same model and validation mechanism • MongoDB is the default database
  • 26. type SignupFormModel struct { ! Email model.Email `gostart:"required"` ! Password1 model.Password `gostart:"required|label=Password|minlen=6"` ! Password2 model.Password `gostart:"label=Repeat password"` } func (self *SignupFormModel) Validate(metaData model.MetaData) []*model.ValidationError { ! if self.Password1 != self.Password2 { ! ! return model.NewValidationErrors(os.NewError("Passwords don't match"), metaData) ! } ! return model.NoValidationErrors } form := &Form{ ! ButtonText: "Signup", ! FormID: "user_signup", ! GetModel: func(form *Form, context *Context) (interface{}, error) { ! ! return &SignupFormModel{}, nil ! }, ! OnSubmit: func(form *Form, formModel interface{}, context *Context) (err error) { ! ! m := formModel.(*SignupFormModel) ! ! // ... create user in db and send confirmation email ... ! ! return err ! }, }
  • 28. type ExampleDoc struct { ! mongo.DocumentBase `bson:",inline"` // Give it a Mongo ID ! Person mongo.Ref `gostart:"to=people"` // Mongo ID ref to a document in "people" collection ! LongerText model.Text `gostart:"rows=5|cols=80|maxlen=400"` ! Integer model.Int `gostart:"min=1|max=100"` ! Email model.Email // Normalization + special treament in forms ! PhoneNumber model.Phone // Normalization + special treament in forms ! Password model.Password // Hashed + special treament in forms ! SubDoc struct { ! ! Day model.Date ! ! RealFloat model.Float `gostart:"valid" ! ! Drinks []mongo.Choice `gostart:"options=Beer,Wine,Water"` ! } }
  • 30. var ExampleDocs *mongo.Collection = mongo.NewCollection("exampledocs", (*ExampleDoc)(nil))
  • 32. i := models.Users.Filter("Name.Last", "Smith").Sort("Name.First").Iterator(); for doc := i.Next(); doc != nil; doc = i.Next() { ! user := doc.(*models.User) ! // ... } // Err() returns any error after Next() returned nil: if i.Err() != nil { ! panic(i.Err()) }
  • 33. Create, modify, save a mongo.Document
  • 34. user := models.Users.NewDocument().(*models.User) user.Name.First.Set("Erik") user.Name.Last.Set("Unger") doc, err := models.Groups.Filter(“Name”, “testgroup”).One() group := doc.(*models.Group) user.Group.Set(group) // sets a mongo.Ref to the group ! err := user.Save()
  • 35. Additional packages • Email (message creation missing in standard mail package + Google Mail defaults) • Gravatar • RSS parsing • Amiando event management (used by http://startuplive.in)
  • 36. Where to get it • go get -u github.com/ungerik/go-start • Documentation: http://go-start.org/
  • 38.
  • 39.
  • 40. We are hiring! STARTeurope
  • 42. The End Questions? • erik.unger@starteurope.at • Twitter: @ungerik • Skype: ungerik

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n