Giter Club home page Giter Club logo

coprl's Introduction

COmmon PResenter Language (COPRL)

alt text

TLDR;

Do you wish you could write a modern user interface in Ruby?

Now you can. Presenters are a Ruby DSL for rendering user interfaces.

  • Presenters are a power washer for building user interfaces
  • Presenters are to HTML/User Interfaces what C is to assembly
  • A presenter generates a Presenter Object Model (POM)
  • A POM fully describes a user interface
  • A POM client can fully render user interface from POM

The semantics are adopted from Material Design.

Why?

Building a user interface should like Ruby itself:

... a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.

Instead building a user interface has turned into:

How many languages/technologies/frameworks do I need to learn to build a rich user interface/experience?"

A typical web client requires at a minimum the following: HTML, CSS, Javascript, in addition we need Ruby on the server, plus some SQL.
That is 5 technologies/languages. Now lets talk about a new client like an iOS or Android client. If we go native, we can now add Java and Swift to that list. We are up to 7 technologies/languages! We didn't even add any popular extras like coffeescript, haml, sass, and we left out frameworks.

What if you could write all your user interface in Ruby and have it rendered natively in ANY client? The COPRL enable that. It is a Ruby DSL that describes a user interface. It generates an intermediate Presenter Object Model (POM). The POM is a declarative user interface that can be rendered by a POM client. The presenters gem provides a web client as a fully functional implementation that both renders natively as a Rails templating engine and as a Rack app.

This concept was initially inspired by the Presenters concepts of Ivar Jacobson as presented by Robert Martin.

Demo

Demo

Or to run locally:

git clone [email protected]:rx/presenters.git
cd presenters/
bundle install
bundle exec rackup

open http://localhost:9292

Note: Demo defaults to Ruby version 2.7.3 in the .ruby-version file. If you want to run a different version -- set RBENV_VERSION to your desired version. For example:

RBENV_VERSION=2.5.5 bundle insatall
RBENV_VERSION=2.5.5 bundle exec rackup```

To see the POM:

open http://localhost:9292/index.pom

Usage

Rails

Presenters are a view templating language in Rails. You can mix and match presenters with your existing views, use them as new views, or call them as partials in existing views.

1) Add presenters to Gemfile

gem 'coprl'

2) Require coprl in config/application.rb

require 'coprl'

3) Mount presenters in config/routes.rb

mount Coprl::Presenters::Rails::Engine => "/"

4) Create the file app/view/hello_world.html.pom with the contents

Coprl::Presenters.define(:hello_world) do
  heading 'hello world'
end   

Navigate to locahost:3000/hello_world

Use the Demo to get example code to drop into your presenters.

Optional — Setting the root route

If you name a presenter :index and want the root of the app to serve up that presenter add the following to your config/initializers/routes.rb

root 'coprl#show'

Optionally — use presenters as partials from ERB/HAML

You can render a presenter as a partial from other templating laguages (erb, haml):

<%= render 'show', presenter: 'hello_world' %> 

You need to add the following to your layout to use presenters as a partial alongside other erb's, haml or any other rails templating language.

Inside the <head> tag add the following:
  <title><%= @pom.page.title if @pom.page %></title>
  <%= coprl_headers %> 
Inside the <body> tag, around you existing yield add the following:
<%= with_presenters_wrapper do %>
<%= yield %>
<%= end %>

Rack

1) To use it, add this line to your Gemfile:

gem 'coprl'

2) Create the file app/presenters/index.pom with the contents:

Coprl::Presenters.define(:hello_world) do
  heading 'hello world'
end   

Presenters are rack based. If your framework uses a rack config file add the following: use Coprl::Presenters::WebClient::App # the api is optional
# use Coprl::Presenters::Api::App

Start your app and goto /hello_world

Use the Demo to get example code to drop into your presenters.

Status

This project is in a released status.

License

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/rx/presenters.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the COPRL project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

coprl's People

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

coprl's Issues

web client: Flatpickr elements are never cleaned up

During initialization, the various date/time components (date, time, date_time) create Flatpickr elements, which are hoisted up out of the component DOM subtree and up into the <body>. When these date/time components are destroyed, the component DOM chunk is removed, but the associated Flatpickr elements are kept around and never cleaned up.

To Reproduce

COPRL::Presenters.define(:date_field) do
  content id: :date_field do
    date_time name: :start_date

    button 'Replace' do
      # this `replaces` tears down the #date_field chunk of DOM, but the hoisted
      # Flatpicker element remains in the body across each replace.
      replaces :date_field, :date_field
    end
  end
end

Expected behavior

When date/time components are removed from the DOM, their associated Flatpickr element(s) should also be removed.

Screenshots
Screenshot 2023-08-30 at 15 22 55

Events on menu items fire twice

Describe the bug
Events attached to menu > items in the web client fire twice.

To Reproduce
Steps to reproduce the behavior:

  1. write a menu with an item that has events, e.g.:
    menu do
      item 'click me' do
        event :click do
          loads 'https://example.com', target: '_blank'
        end
      end
    end
  2. click the menu item
  3. Two tabs open to https://example.com (or, in my case, one tab opens and Chrome blocks a pop-up for the second)

Expected behavior
Only one tab/window should open to https://example.com.

Screenshots
Screenshot 2023-11-28 at 08 59 34

Desktop (please complete the following information):

  • OS: macOS, Windows
  • Browser: Chrome
  • Version: 119

Semantic release doesn't generate a release

Describe the bug
Semantic release doesn't generate a release:

[2:17:47 PM] [semantic-release] › ℹ  This test run was triggered on the branch main, while semantic-release is configured to only publish from 2.x, master, therefore a new version won’t be published.

2.x used to be the repo's main branch, but it is now main.

To Reproduce
Steps to reproduce the behavior:

  1. Run the semantic-release action
  2. Observe the lack of new releases generated

Expected behavior

A new release is published.

Empty events generate an error

Describe the bug
Empty event blocks generate a client-side JS error.

To Reproduce
Given the following code,

button 'click' do
  if false
    puts "you'll never see me"
  end
end
  1. Click the button
  2. Observe the browser's JS console:
If you got here it may not be what you think: TypeError: Cannot read properties of undefined (reading 'contentType')

Additionally, an error block is displayed to the user on the page or near the faulting element.

Expected behavior
No error should be generated if an event's block is empty.

Screenshots
image (1)

Desktop (please complete the following information):

  • OS: macOS
  • Browser: Chrome
  • Version: 109.0.5414.119 (x86_64)

Add support for automation test identifiers

Add support for automation test identifiers in the DSL, specifically data-testid for the web client.

Describe alternatives you've considered

  • relying on CSS selectors or XPath queries can be brittle
  • relying on id would overload the attribute between event action logic (e.g. hides :some_id) and test element selection
  • element content is unreliable, especially when apps have been translated/localized
  • should the generated attribute name be configurable?

Additional context

Regression: `button` doesn't pick up caller-provided class names

Describe the bug
The 3.0.0 release introduced a regression (ec755ae) which prevents the web client from rendering additional class names provided to button components. class_name is added to forwarded_locals before additional caller-provided class names are appended to class_name. The additional classes aren't passed to the subsequent ERB template.

To Reproduce
Steps to reproduce the behavior:

button 'Sign in', full_width: true, class: 'meow' do
  # ...
end
<button type="button" class="v-button v-button--button mdc-button mdc-button--raised v-component mdc-ripple-upgraded--unbounded mdc-ripple-upgraded">Sign in</button>

Expected behavior
The above should render a button with class "v-button-full-width meow", but none of these class names are present.

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.