Giter VIP home page Giter VIP logo

engel's Introduction

Engel

PyPI PyPI PyPI Code Climate

Engel is an opinionated framework that allows you to painlessly build cross-platform web interfaces for your projects.

Take a look at the documentation for more details.

Installation

Via pip

$ pip install engel

Manually

$ git clone https://github.com/Dalloriam/engel
$ cd engel
$ python setup.py install

Running the tests

$ python setup.py test

Building a basic web interface with Engel

In this example, we will build a web front-end to a text file. Exciting, right?

Specifications

  • Write lines to a text file.
  • Display all lines of a text file.
from engel.application import Application, View

from engel.widgets.structure import List
from engel.widgets.forms import Button, TextBox
from engel.widgets.text import Title, Span

from engel.libraries import bootstrap4

import os


class FileService(object):
  """Services are the main way of interacting with the outside world with Engel.
  This service encapsulates all interactions with our file, and will be made
  available to our application.
  """
  def __init__(self):
    if not os.path.isfile('myfile.txt'):
      open('myfile.txt', 'a').close()

  def get_all(self):
    with open("myfile.txt", "rU") as infile:
      return list(filter(bool, infile.readlines()))

  def add(self, txt):
    with open("myfile.txt", "a") as outfile:
      outfile.write(txt + "\n")


class MainFileView(View):
  """With Engel, views represent the structure of the page currently displayed
  as well as the different actions handled by the program.
  """
  title = "MyFile.txt"

  current_id = 0

  libraries = [bootstrap4]

  def build(self):
    """The build() method is called when the application is rendering the page to
    HTML. It is responsible for building the DOM and enqueuing the event handlers required by the view.
    """

    # We create a bootstrap Container() object and anchor it to the root of the page.
    main_panel = bootstrap4.Container(id="containerMain", parent=self.root)
    Title(id="pageTitle", text="Contents of myfile.txt", parent=main_panel)

    # Here, we define a List() object. Contrary to Container(), List() is more than
    # a simple wrapper around <ul>. The List object provides an interface very similar to python's list,
    # and at the same time provides the auto-updating capabilities of Engel widgets.
    self.lines_list = List(id="lstLines", parent=main_panel)

    # We get the list of active services from the view's context & call the
    # method allowing us to retrieve all lines in the file.
    for ln in self.context.services["FileService"].get_all():
      self.append_line(ln)

    self.txtNew = TextBox(id="txtNew", name="txtNew", parent=main_panel)
    btn = Button(id="btnSubmit", text="Add Line", parent=main_panel)

    # Note: The framework handles seamlessly the forwarding of events from the
    # client to the server, so we can set a server-side method as callback
    # for a client event.
    self.on(event="click", callback=self.create_line, selector="#" + btn.id)

  def append_line(self, ln):
    self.lines_list.append(Span(id="line_" + str(self.current_id), text=ln))
    self.current_id += 1

  def create_line(self, event, interface):
    new_line = self.txtNew.text
    self.context.services["FileService"].add(new_line)
    self.append_line(new_line)

    # Note: The framework also handles the updating of client widgets from the server. This means
    # that the HTML view is guaranteed to always be in sync with your python objects.
    self.txtNew.text = ""


class FileApp(Application):
  """The Application object is the central object tying your Engel app together.
  It holds all the information common to all views, as well as view and service
  definitions.
  """

  # The base title of the app.
  # The actual title of the page is set by App.base_title.format(view.title)
  base_title = "{0} | TextFileManager"

  def __init__(self, debug=False):
    super(FileApp, self).__init__(debug)

    self.views["default"] = MainFileView

    # Services are instanciated on app startup and are kept running for the
    # entire lifetime of the app.
    self.services["FileService"] = FileService


if __name__ == "__main__":
  app = FileApp(debug=True)
  app.start()

Getting it running

To start the app, simply run

$ python [appfilename].py

App running

Not so pretty, but it works great!

Requirements

  • Python 3.5.1 (Not tested yet on earlier versions, should work with 3.x)

engel's People

Contributors

dalloriam avatar theyouishere avatar

Watchers

jm avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.