glimmer-dsl-web 0.6.5 → 0.6.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -2
- data/README.md +67 -12
- data/VERSION +1 -1
- data/glimmer-dsl-web.gemspec +5 -4
- data/lib/glimmer/dsl/web/element_expression.rb +5 -0
- data/lib/glimmer/web/element_proxy.rb +10 -1
- data/lib/rails/resource_service.rb +76 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 542796633baef10477c8cda0c134586e6fda1cb7b9b335d618525fa889f14f2b
|
4
|
+
data.tar.gz: c35bc5b7d2a1290e700fea1853470f102351993d4a9747764a16b560bca36050
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb2ed76d330dc4b503890e216d352210fd50fe2a1590883df31964853c7bd707857fc201c6ae102a507ed844bcd94537f318a86682a874f66448206bafa90bd0
|
7
|
+
data.tar.gz: f5836f4e4e8f0d377f54e1a16198a29bf0db10c28dc23a4a758435809ebc48b8982e882bcc1e408dce6d79db1ed11b5df237e8ee7f404a4e1f72fff5eab4f298
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.6.6
|
4
|
+
|
5
|
+
- `Rails::ResourceService` supports index/show/create/update/destory REST API calls for any Rails resources
|
6
|
+
- Support being able to set or data-bind `title` property on HTML elements
|
7
|
+
- Restrict use of `title` tag to within a `head` element only
|
8
|
+
|
3
9
|
## 0.6.5
|
4
10
|
|
5
11
|
- Ensure clearing input datetime/date/time/month values sends `nil` to the data-bound model attribute (not `''`, which caused issues)
|
6
|
-
- Support data-binding input month
|
7
|
-
- Fix issue with clearing date/time
|
12
|
+
- Support data-binding input month value to a model attribute that has a datetime value
|
13
|
+
- Fix issue with clearing date/time in Hello, Input Date/Time! causing errors in the web browser console
|
8
14
|
|
9
15
|
## 0.6.4
|
10
16
|
|
data/README.md
CHANGED
@@ -1,23 +1,27 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.6.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.6.6 (Beta)
|
2
2
|
## Ruby-in-the-Browser Web Frontend Framework
|
3
|
-
### The "Rails" of Frontend Frameworks!!!
|
3
|
+
### The "Rails" of Frontend Frameworks!!! ([Fukuoka Award Winning](https://andymaleh.blogspot.com/2025/01/glimmer-dsl-for-web-wins-in-fukuoka.html))
|
4
4
|
#### Finally, Ruby Developer Productivity, Happiness, and Fun in the Frontend!!!
|
5
5
|
[](http://badge.fury.io/rb/glimmer-dsl-web)
|
6
6
|
[](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
7
7
|
|
8
8
|
**(Based on Original [Glimmer](https://github.com/AndyObtiva/glimmer) Library Handling World’s Ruby GUI Needs Since 2007. Beware of Imitators!)**
|
9
9
|
|
10
|
+
**([Fukuoka Prefecture Future IT Initiative 2025 Money Forward Award Winner](https://andymaleh.blogspot.com/2025/01/glimmer-dsl-for-web-wins-in-fukuoka.html))**
|
11
|
+
|
10
12
|
**(Talk Videos: [Intro to Ruby in the Browser](https://youtu.be/4AdcfbI6A4c?si=MmxOrkhIXTDHQoYi) / [Frontend Ruby with Glimmer DSL for Web \[Montreal.rb\]](https://youtu.be/rIZ-ILUv9ME?si=raygUXVPd_7ypWuE) / [Frontend Ruby with Glimmer DSL for Web \[/dev/mtl 2024\]](https://www.youtube.com/watch?v=J2VIY9DMJo4))**
|
11
13
|
|
12
14
|
**(Ruby Rogues Podcast: [Building Better Ruby Apps: Glimmer Component Slots and More](https://topenddevs.com/podcasts/ruby-rogues/episodes/building-better-ruby-apps-glimmer-s-component-slots-and-more-ruby-653))**
|
13
15
|
|
14
16
|
[](https://sample-glimmer-dsl-web-rails7-app-black-sound-6793.fly.dev/)
|
15
17
|
|
18
|
+
**Endorsement:** *"I'd like to endorse Andy Maleh’s work (Glimmer DSL for Web). I got introduced to it at RubyConf 2024 and have been playing around with it pretty successfully. What I have found most interesting is that I have been writing inside of a rails app, where I have been running the same code for models and presenters inside of MRI rspec. That way I can write tests that verify behavior of the presenters and models and still see them run successfully in the browser. That allows me to have a very nice cycle of refactoring and being confident in my changes without even running it in browser. I just assume that the binding will work and it usually works perfectly."* - Steve Tuckner on January 9, 2024
|
19
|
+
|
16
20
|
You can finally live in pure Rubyland on the Web in both the frontend and backend with [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web)! [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Web enables building Web Frontends (aka SPA: Single Page Applications) using [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c), as per [Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby](https://youtu.be/knutsgHTrfQ?t=789). It supports Rails' principle of the One Person Framework by not requiring any extra developers with JavaScript expertise, yet enabling Ruby (Backend) Software Engineers to develop the Frontend with Ruby code that is better than any JavaScript code produced by JS developers. It aims at providing the simplest, most intuitive, most straight-forward, and most productive frontend framework in existence. The framework follows the Ruby way (with [DSLs](https://martinfowler.com/books/dsl.html) and [TIMTOWTDI](https://en.wiktionary.org/wiki/TMTOWTDI#English)) and the Rails way ([Convention over Configuration](https://rubyonrails.org/doctrine)) in building Isomorphic Ruby on Rails Applications. It provides a Ruby [HTML DSL](#usage) (including full support for [SVG](#hello-svg)), which uniquely enables writing both structure code and logic code in one language. It supports both Unidirectional (One-Way) [Data-Binding](#hello-data-binding) (using `<=`) and Bidirectional (Two-Way) [Data-Binding](#hello-data-binding) (using `<=>`). Dynamic rendering (and re-rendering) of HTML content is also supported via [Content Data-Binding](#hello-content-data-binding). Modular design is supported with [Glimmer Web Components](#hello-component), [Component Slots](#hello-component-slots), and [Component Custom Event Listeners](#hello-component-listeners). And, a Ruby CSS DSL is supported with the included [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css). To automatically convert legacy HTML & CSS code to Glimmer DSL Ruby code, Software Engineers could use the included [`html_to_glimmer`](https://github.com/AndyObtiva/glimmer-dsl-xml#html-to-glimmer-converter) and [`css_to_glimmer`](https://github.com/AndyObtiva/glimmer-dsl-css#css-to-glimmer-converter) commands. Many [samples](#samples) are demonstrated in the [Rails sample app](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app) (there is a very minimal [Standalone [No Rails] static site sample app](https://github.com/Largo/glimmer-dsl-web-standalone-demo) too).
|
17
21
|
|
18
22
|
You can finally have Ruby developer happiness and productivity in the Frontend! No more wasting time splitting your resources across multiple languages, using badly engineered, over-engineered, or premature-optimization-obsessed JavaScript libraries, fighting JavaScript build issues (e.g. webpack), or rewriting Ruby Backend code in Frontend JavaScript. With [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c), you can have an exponential jump in development productivity (2x or higher), time-to-release (1/2 or less time), cost (1/2 or cheaper), and maintainability (~50% the code that is simpler and more readable) over JavaScript libraries like React, Angular, Ember, Vue, and Svelte, while being able to reuse Backend Ruby code as is in the Frontend for faster interactions when needed. Also, with Frontend Ruby SPA (Single Page Applications), companies can cut their hiring budget in half by having Backend Ruby Software Engineers do Frontend Development in Ruby! [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c) finally fulfills every smart highly-productive Rubyist's dream by bringing Ruby productivity fun to Frontend Development, the same productivity fun you had for years and decades in Backend Development.
|
19
23
|
|
20
|
-
[Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) aims to be a very simple Ruby-based SPA drop-in replacement for your existing JavaScript Frontend SPA library (e.g. React, Angular, Vue, Ember, Svelte) or your JavaScript Frontend layer in general. It does not change how your Frontend interacts with the Backend, meaning you can continue to write Rails Backend API endpoints as needed and make HTTP/Ajax requests or read data embedded in elements, but from [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c). Whatever is possible in JavaScript is possible when using Glimmer DSL for Web as it integrates with any existing JavaScript library. The [Rails sample app](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app) demonstrates how to [make HTTP calls](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/sample_selector/models/sample_api.rb) and how to [integrate with a JavaScript library](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/views/layouts/application.html.erb) (highlightjs) that performs [code syntax highlighting](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/sample_selector.rb). [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) currently runs on [Opal](https://opalrb.com/) ([Fukuoka Ruby 2023 Award Winner](https://www.digitalfukuoka.jp/topics/228?locale=ja)), a Ruby-to-JavaScript transpiler. In the future, it might support other Frontend Ruby environments, such as [ruby.wasm](https://github.com/ruby/ruby.wasm).
|
24
|
+
[Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) aims to be a very simple Ruby-based SPA drop-in replacement for your existing JavaScript Frontend SPA library (e.g. React, Angular, Vue, Ember, Svelte) or your JavaScript Frontend layer in general. It does not change how your Frontend interacts with the Backend, meaning you can continue to write Rails Backend API endpoints as needed and make HTTP/Ajax requests or read data embedded in elements, but from [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c). Whatever is possible in JavaScript is possible when using Glimmer DSL for Web as it integrates with any existing JavaScript library. The [Rails sample app](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app) demonstrates how to [make HTTP calls](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/sample_selector/models/sample_api.rb) or [Rails REST API index/show/create/update/destroy web requests for Resources](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/contact_manager/presenters/contact_presenter.rb) via [Rails::ResourceService](/lib/rails/resource_service.rb) and how to [integrate with a JavaScript library](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/views/layouts/application.html.erb) (highlightjs) that performs [code syntax highlighting](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/sample_selector.rb). [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) currently runs on [Opal](https://opalrb.com/) ([Fukuoka Ruby 2023 Award Winner](https://www.digitalfukuoka.jp/topics/228?locale=ja)), a Ruby-to-JavaScript transpiler. In the future, it might support other Frontend Ruby environments, such as [ruby.wasm](https://github.com/ruby/ruby.wasm).
|
21
25
|
|
22
26
|
After looking through the [samples](#samples) below, read the [FAQ (Frequently Asked Questions)](#faq) to learn more about how Glimmer DSL for Web compares to other approaches/libraries like Hotwire (Turbo), Phlex, ViewComponent, Angular, Vue, React, Svelte, and other JS frameworks.
|
23
27
|
|
@@ -1377,11 +1381,11 @@ Learn more about the differences between various [Glimmer](https://github.com/An
|
|
1377
1381
|
|
1378
1382
|
## Setup
|
1379
1383
|
|
1380
|
-
You can setup Glimmer DSL for Web in [Rails 7](#rails-7)
|
1384
|
+
You can setup Glimmer DSL for Web in [Rails 7](#rails-7) or [Standalone (No Rails)](#standalone-no-rails).
|
1381
1385
|
|
1382
1386
|
Once done, read [Usage](#usage) instructions. Note that for serious app usage, it is recommended to build [components](#hello-component) and use the [`glimmer_component` Rails Helper](#hello-glimmer_component-rails-helper) to embed the top-level Web Frontend component in a Rails View.
|
1383
1387
|
|
1384
|
-
(NOTE: Keep in mind this is a Beta. If you run into issues, try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-web/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
|
1388
|
+
(NOTE: Keep in mind this is a Beta. If you run into issues, read the [FAQ](#faq) in case they are addressed there (e.g. [I sometimes get an Opal error that makes no sense in relation to my code. How do I fix it?](https://github.com/AndyObtiva/glimmer-dsl-web/blob/master/README.md#i-sometimes-get-an-opal-error-that-makes-no-sense-in-relation-to-my-code-how-do-i-fix-it)) and try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-web/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
|
1385
1389
|
|
1386
1390
|
### Rails 7
|
1387
1391
|
|
@@ -1404,7 +1408,7 @@ rails new glimmer_app_server
|
|
1404
1408
|
Add the following to `Gemfile`:
|
1405
1409
|
|
1406
1410
|
```
|
1407
|
-
gem 'glimmer-dsl-web', '~> 0.6.
|
1411
|
+
gem 'glimmer-dsl-web', '~> 0.6.6'
|
1408
1412
|
```
|
1409
1413
|
|
1410
1414
|
Run:
|
@@ -1616,6 +1620,8 @@ Andreas Idogawa-Wildi ([@Largo](https://github.com/Largo)) created a project tha
|
|
1616
1620
|
|
1617
1621
|
## Usage
|
1618
1622
|
|
1623
|
+
### Glimmer HTML DSL
|
1624
|
+
|
1619
1625
|
Glimmer DSL for Web offers a HTML DSL ([Graphical User Interface](https://en.wikipedia.org/wiki/Graphical_user_interface) [Domain Specific Language](https://en.wikipedia.org/wiki/Domain-specific_language)) for building HTML Web User Interfaces declaratively in Ruby.
|
1620
1626
|
|
1621
1627
|
1- **Keywords (HTML Elements)**
|
@@ -1690,6 +1696,40 @@ Next, check out [Samples](#samples).
|
|
1690
1696
|
|
1691
1697
|
Note that for serious app usage, it is recommended to build [components](#hello-component) and use the [`glimmer_component` Rails Helper](#hello-glimmer_component-rails-helper) to embed the top-level Web Frontend component in a Rails View.
|
1692
1698
|
|
1699
|
+
### Rails::ResourceService
|
1700
|
+
|
1701
|
+
To make REST API calls (web requests) to the Backend of a Rails application in order to index/show/create/update/delete resources,
|
1702
|
+
you can use [Rails::ResourceService](/lib/rails/resource_service.rb) (`require 'rails/resource_service'` to use). Consult
|
1703
|
+
the `Rails::ResourceService` class source code to find out what its API is. It can work with a basic Rails Scaffold of a Resource
|
1704
|
+
if Developers would rather not write the Backend by hand.
|
1705
|
+
|
1706
|
+
Example from [ContactPresenter](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/contact_manager/presenters/contact_presenter.rb) in the [Contact Manager](#contact-manager) sample:
|
1707
|
+
|
1708
|
+
`form_contact` is an instance of the [Contact](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/contact_manager/models/contact.rb) class.
|
1709
|
+
|
1710
|
+
```ruby
|
1711
|
+
Rails::ResourceService.update(resource: form_contact) do |response|
|
1712
|
+
if response.ok?
|
1713
|
+
updated_contact_response_body = Native(response.body)
|
1714
|
+
updated_contact = form_contact.clone
|
1715
|
+
updated_contact.updated_at = updated_contact_response_body.updated_at
|
1716
|
+
contacts[edit_index].load_with(updated_contact)
|
1717
|
+
self.edit_index = nil
|
1718
|
+
form_contact.reset
|
1719
|
+
form_contact.errors = nil
|
1720
|
+
else
|
1721
|
+
form_contact.errors = JSON.parse(response.body)
|
1722
|
+
end
|
1723
|
+
end
|
1724
|
+
```
|
1725
|
+
|
1726
|
+
Note that there are alternative ways of invoking the `Rails::ResourceService.update` call:
|
1727
|
+
- `Rails::ResourceService.update(resource: form_contact)`
|
1728
|
+
- `Rails::ResourceService.update(resource_class: Contact, resource_id: form_contact.id, resource_attributes: {first_name: form_contact.first_name, ...})`
|
1729
|
+
- `Rails::ResourceService.update(singular_resource_name: 'contact', resource_id: form_contact.id, resource_attributes: {first_name: form_contact.first_name, ...})`
|
1730
|
+
- `Rails::ResourceService.update(update_resource_url: "/contacts/#{form_contact.id}.json", resource_attributes: {first_name: form_contact.first_name, ...})`
|
1731
|
+
- `Rails::ResourceService.update(update_resource_url: "/contacts/#{form_contact.id}.json", params: {contact: {first_name: form_contact.first_name, ...}})`
|
1732
|
+
|
1693
1733
|
## Supported Glimmer DSL Keywords
|
1694
1734
|
|
1695
1735
|
[All HTML elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element), following the Ruby method name standard of lowercase and underscored names.
|
@@ -4503,6 +4543,18 @@ end
|
|
4503
4543
|
|
4504
4544
|

|
4505
4545
|
|
4546
|
+
#### Contact Manager
|
4547
|
+
|
4548
|
+
The Contact Manager sample demonstrates talking to the Rails Backend by making create/update/destory REST API calls
|
4549
|
+
to RESTful Resources via the `Rails::ResourceService` class that is included in Glimmer DSL for Web
|
4550
|
+
(`require 'rails/resource_service'` to use).
|
4551
|
+
|
4552
|
+
[https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/contact_manager.rb](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/contact_manager.rb)
|
4553
|
+
|
4554
|
+
[https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/contact_manager](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/blob/master/app/assets/opal/contact_manager)
|
4555
|
+
|
4556
|
+

|
4557
|
+
|
4506
4558
|
## Design Principles
|
4507
4559
|
|
4508
4560
|
- The Ruby Way (including TIMTOWTDI: There Is More Than One Way To Do It)
|
@@ -4544,30 +4596,33 @@ Learn more by reading the [GPG](https://github.com/AndyObtiva/glimmer/blob/maste
|
|
4544
4596
|
|
4545
4597
|
F.A.Q. (Frequently Asked Questions):
|
4546
4598
|
|
4547
|
-
|
4599
|
+
#### Can I reuse JavaScript libraries from Glimmer DSL for Web in Ruby?
|
4548
4600
|
|
4549
4601
|
Absolutely. Glimmer DSL for Web can integrate with any JavaScript libraries. You can either load the JavaScript libraries in advance by linking to them in the Rails View/Layout (e.g. linking to JS library CDN URLs) or by including JavaScript files in the lookup directories of Opal Ruby, and adding a Ruby `require('path_to_js_lib')` call in the code. In Ruby, the `$$` global variable gives access to the top-level JavaScript global scope, which enables invocations on any JavaScript objects. For example, `$$.hljs` gives access to the loaded `window.hljs` object for the Highlight.js library, and that enables invoking any functions from that library as needed, like `$$.hljs.highlightAll` to activate code syntax highlighting.
|
4550
4602
|
|
4551
|
-
|
4603
|
+
#### How does Glimmer DSL for Web compare to Rails Hotwire (Turbo)?
|
4552
4604
|
|
4553
4605
|
Glimmer DSL for Web is a Frontend library, meaning it replaces the JavaScript layer in a web application (e.g. Rails app) with Ruby code. On the other hand, Rails Hotwire (Turbo) is mostly a Backend-driven technology that enables automatically replacing HTML DOM elements with HTML markup sent over the wire from a Rails Backend. So, the two technologies are mostly orthogonal, but can be used in the same Rails web application, albeit exclusively on separate web pages at the moment. In the future, we might explore supporting the ability to combine both technologies in the same pages, but until then, use on separate pages. Glimmer DSL for Web can handle any sort of Frontend interactions even without making HTTP calls to the Backend, so it can implement more use-cases than Hotwire. Using Glimmer DSL for Web with Rails API end-points is simpler than using Hotwire overall. That is because Glimmer Content Data-Binding is a simpler version of Turbo Frames that does not require worrying about setting and using element IDs (as that is handled automatically) and that operates at a more correct abstraction level for how we think about View component updates in relation to Model changes (we make updates at the Model layer, and they automatically get reflected in the View through data-binding). Also, Glimmer DSL for Web supports Glimmer Web Components, which enable better division and organization of View code into modular components than ERB plus having higher readability. It is true that Hotwire is an improvement over using JavaScript frameworks like React when there is not much logic beyond updating elements with Server-Side rendered HTML. And, Glimmer DSL for Web is the next big advancement that provides an even simpler approach while also giving you full Frontend Development capabilities using Ruby in the Browser.
|
4554
4606
|
|
4555
|
-
|
4607
|
+
#### How does Glimmer DSL for Web compare to Phlex or ViewComponent?
|
4556
4608
|
|
4557
4609
|
Glimmer DSL for Web is a Frontend library, meaning it replaces the JavaScript layer in a web application (e.g. Rails app) with Ruby code while providing its own View-layer component support using [`Glimmer::Web::Component`](#hello-component). On the other hand, Phlex and ViewComponent are Backend View-layer component libraries, so they serve 100% orthogonal needs, and can be used side by side with Glimmer DSL for Web if needed (e.g. Phlex components can consist of Backend HTML elements + Glimmer components that are rendered in the Frontend). That said, Phlex came out years after previous Glimmer libraries like Glimmer DSL for SWT, and Phlex's component system is very similar to Glimmer's component system in Glimmer DSL for SWT (perhaps inspired by it unconsciously or consciously). So, if you like Phlex in the Backend, you'll love Glimmer DSL for Web in the Frontend.
|
4558
4610
|
|
4559
|
-
|
4611
|
+
#### How does Glimmer DSL for Web compare to Angular, React, Vue, Svelte, or other JS frameworks?
|
4560
4612
|
|
4561
4613
|
Without delving into details, Glimmer DSL for Web is meant to be a Ruby-based drop-in replacement for Angular, React, Vue, Svelte, and other JS frameworks. Glimmer Ruby code is transpiled to JavaScript, so it has JavaScript performance in general, which is not that far from that of Angular, React, or Vue. Glimmer DSL for Web has outperformed React by a factor of 33.33% in rendering 3000+ elements in a realistic app scenario that was benchmarked recently (in Oct 2024). Additionally, it enables writing both structure code and logic code in the same language (Ruby), greatly simplifying maintainability and improving productivity by eliminating multi-language dissonance and friction that drags down productivity as there is no need anymore to think in multiple languages unnecessarily, use XML based solutions (e.g. JSX), or use templating solutions (e.g. Mustache). Lastly, Glimmer DSL for Web supports familiar Software Engineering architectural patterns like Model-View-Controller and Model-View-Presenter, enabling Software Engineers to write the lightest and simplest code possible for building Web frontends in Ruby, with the best separation of concerns. Software Engineers can finally become happy Ruby developers by writing Ruby code in the Frontend too now in addition to the Backend.
|
4562
4614
|
|
4563
|
-
|
4615
|
+
#### How do I have a Glimmer Web Component re-render in a similar way to how React components re-render?
|
4564
4616
|
|
4565
4617
|
[Content Data-Binding](#hello-content-data-binding) supports re-rendering dynamic parts of a Glimmer Web Component (or the full component if all of it is dynamic). Glimmer DSL for Web simplifies Frontend Development significantly over React by not re-rendering everything if not needed (regardless of use of Virtual DOM) yet only re-rendering the parts of a component that do change dynamically. As a result, Software Engineers do not have to worry about the ripple effect of full re-renders or the possibility of breaking some parts of a page when making small changes to a single component in a hierarchy of page components. And, if only an element property changes, [Content Data-Binding](#hello-content-data-binding) is not even needed. It is much simpler to rely on simple [Property Data-Binding](#hello-data-binding) in that case. This makes reasoning about Glimmer DSL for Web Ruby code a lot simpler than reasoning about React component JavaScript code.
|
4566
4618
|
|
4567
|
-
|
4619
|
+
#### How do I reuse React components from Glimmer DSL for Web?
|
4568
4620
|
|
4569
4621
|
In the future, support for HTML Web Components will be added, and that will enable reuse of React components by using a library that converts them to HTML Web Components first like [react-to-web-component](https://github.com/bitovi/react-to-web-component) or [react-webcomponent](https://github.com/adobe/react-webcomponent).
|
4570
4622
|
|
4623
|
+
#### I sometimes get an Opal error that makes no sense in relation to my code. How do I fix it?
|
4624
|
+
|
4625
|
+
That happens randomly sometimes (e.g. `Uncaught SyntaxError: Unexpected token ':'`) because of a bug in Sprockets caching of Opal assets (which has been reported to the Opal team). To get around it, try first to restart the Rails server and then refresh the page. If that does not resolve the issue, stop the Rails server, clear tmp/cache (run `rm -rf tmp/cache` to clear cache generated by Opal), start the Rails server again, and refresh the page. This should definitely resolve the issue if it was indeed not caused by your code, yet by the Opal Sprockets caching bug.
|
4571
4626
|
|
4572
4627
|
### Issues
|
4573
4628
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.6
|
data/glimmer-dsl-web.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-web 0.6.
|
5
|
+
# stub: glimmer-dsl-web 0.6.6 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-web".freeze
|
9
|
-
s.version = "0.6.
|
9
|
+
s.version = "0.6.6"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andy Maleh".freeze]
|
14
|
-
s.date = "2025-
|
14
|
+
s.date = "2025-02-17"
|
15
15
|
s.description = "Glimmer DSL for Web (Ruby in the Browser Web Frontend Framework) enables building Web Frontends using Ruby in the Browser, as per Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby. It aims at providing the simplest, most intuitive, most straight-forward, and most productive frontend framework in existence. The framework follows the Ruby way (with DSLs and TIMTOWTDI) and the Rails way (Convention over Configuration) in building Isomorphic Ruby on Rails Applications. It provides a Ruby HTML DSL, which uniquely enables writing both structure code and logic code in one language. It supports both Unidirectional (One-Way) Data-Binding (using <=) and Bidirectional (Two-Way) Data-Binding (using <=>). Dynamic rendering (and re-rendering) of HTML content is also supported via Content Data-Binding. Modular design is supported with Glimmer Web Components, Component Slots, and Component Custom Event Listeners. And, a Ruby CSS DSL is supported with the included Glimmer DSL for CSS. Many samples are demonstrated in the Rails sample app (there is a very minimal Standalone [No Rails] sample app too). You can finally live in pure Rubyland on the Web in both the frontend and backend with Glimmer DSL for Web! This gem relies on Opal Ruby.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -93,7 +93,8 @@ Gem::Specification.new do |s|
|
|
93
93
|
"lib/glimmer/web/element_proxy.rb",
|
94
94
|
"lib/glimmer/web/event_proxy.rb",
|
95
95
|
"lib/glimmer/web/formatting_element_proxy.rb",
|
96
|
-
"lib/glimmer/web/listener_proxy.rb"
|
96
|
+
"lib/glimmer/web/listener_proxy.rb",
|
97
|
+
"lib/rails/resource_service.rb"
|
97
98
|
]
|
98
99
|
s.homepage = "http://github.com/AndyObtiva/glimmer-dsl-web".freeze
|
99
100
|
s.licenses = ["MIT".freeze]
|
@@ -25,6 +25,11 @@ module Glimmer
|
|
25
25
|
args.size == 1 && args.first.is_a?(Hash) ||
|
26
26
|
args.size == 2 && args.first.is_a?(String) && args.last.is_a?(Hash)
|
27
27
|
) &&
|
28
|
+
(
|
29
|
+
keyword != 'title' ||
|
30
|
+
parent.nil? ||
|
31
|
+
parent.keyword == 'head'
|
32
|
+
) &&
|
28
33
|
( # ensure SVG keywords only live under SVG element (unless it's the SVG element itself)
|
29
34
|
!Glimmer::Web::ElementProxy.svg_keyword_supported?(keyword) ||
|
30
35
|
keyword == 'svg' ||
|
@@ -131,6 +131,9 @@ module Glimmer
|
|
131
131
|
].map(&:downcase)
|
132
132
|
|
133
133
|
ELEMENT_KEYWORDS = HTML_ELEMENT_KEYWORDS + SVG_ELEMENT_KEYWORDS
|
134
|
+
|
135
|
+
# title is a special attribute because it matches an element tag name (needs special treatment)
|
136
|
+
HTML_ELEMENT_SPECIAL_ATTRIBUTES = ['title']
|
134
137
|
|
135
138
|
GLIMMER_ATTRIBUTES = [:parent]
|
136
139
|
PROPERTY_ALIASES = {
|
@@ -732,7 +735,13 @@ module Glimmer
|
|
732
735
|
# TODO consider doing more correct checking of availability of properties/methods using native ticks
|
733
736
|
property_name = property_name_for(method_name)
|
734
737
|
unnormalized_property_name = unnormalized_property_name_for(method_name)
|
735
|
-
if method_name.
|
738
|
+
if method_name.end_with?('=') && HTML_ELEMENT_SPECIAL_ATTRIBUTES.include?(property_name)
|
739
|
+
if rendered?
|
740
|
+
dom_element.attr(property_name, *args)
|
741
|
+
else
|
742
|
+
enqueue_post_render_method_call(method_name, *args, &block)
|
743
|
+
end
|
744
|
+
elsif method_name.to_s.start_with?('class_name_')
|
736
745
|
property, sub_property = method_name.to_s.match(REGEX_CLASS_NAME_SUB_PROPERTY).to_a.drop(1)
|
737
746
|
if args.empty?
|
738
747
|
class_name_included(sub_property)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Rails
|
2
|
+
# ResourceService supports index/show/create/update/destory REST API calls for any Rails resources
|
3
|
+
# Automatically loads the authenticity token from meta[name=csrf-token] content attribute
|
4
|
+
# Assumes a resource or resource class that matches the name of a Backend ActiveRecord Model (e.g. Contact class or instance)
|
5
|
+
class ResourceService
|
6
|
+
TIMESTAMP_ATTRIBUTES = ['created_at', 'updated_at']
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def index(resource: nil, resource_class: nil, singular_resource_name: nil, plural_resource_name: nil, index_resource_url: nil, params: nil, &response_handler)
|
10
|
+
resource_class ||= resource&.class
|
11
|
+
singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
|
12
|
+
plural_resource_name ||= "#{singular_resource_name}s"
|
13
|
+
index_resource_url ||= "/#{plural_resource_name}.json"
|
14
|
+
HTTP.get(index_resource_url, payload: index_show_destroy_resource_params(params: params.to_h), &response_handler)
|
15
|
+
end
|
16
|
+
|
17
|
+
def show(resource: nil, resource_class: nil, resource_id: nil, singular_resource_name: nil, plural_resource_name: nil, show_resource_url: nil, params: nil, &response_handler)
|
18
|
+
resource_class ||= resource&.class
|
19
|
+
resource_id ||= resource&.id
|
20
|
+
singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
|
21
|
+
plural_resource_name ||= "#{singular_resource_name}s"
|
22
|
+
show_resource_url ||= "/#{plural_resource_name}/#{resource_id}.json"
|
23
|
+
HTTP.get(show_resource_url, payload: index_show_destroy_resource_params(params: params.to_h), &response_handler)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create(resource: nil, resource_class: nil, resource_attributes: nil, singular_resource_name: nil, plural_resource_name: nil, create_resource_url: nil, params: nil, &response_handler)
|
27
|
+
resource_class ||= resource&.class
|
28
|
+
singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
|
29
|
+
plural_resource_name ||= "#{singular_resource_name}s"
|
30
|
+
create_resource_url ||= "/#{plural_resource_name}.json"
|
31
|
+
HTTP.post(create_resource_url, payload: create_update_resource_params(resource:, resource_class:, resource_attributes:, singular_resource_name:, params: params.to_h), &response_handler)
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(resource: nil, resource_class: nil, resource_id: nil, resource_attributes: nil, singular_resource_name: nil, plural_resource_name: nil, update_resource_url: nil, params: nil, &response_handler)
|
35
|
+
resource_class ||= resource&.class
|
36
|
+
resource_id ||= resource&.id
|
37
|
+
singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
|
38
|
+
plural_resource_name ||= "#{singular_resource_name}s"
|
39
|
+
update_resource_url ||= "/#{plural_resource_name}/#{resource_id}.json"
|
40
|
+
HTTP.patch(update_resource_url, payload: create_update_resource_params(resource:, resource_class:, resource_attributes:, singular_resource_name:, params: params.to_h), &response_handler)
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy(resource: nil, resource_class: nil, resource_id: nil, singular_resource_name: nil, plural_resource_name: nil, destroy_resource_url: nil, params: nil, &response_handler)
|
44
|
+
resource_class ||= resource&.class
|
45
|
+
resource_id ||= resource&.id
|
46
|
+
singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
|
47
|
+
plural_resource_name ||= "#{singular_resource_name}s"
|
48
|
+
destroy_resource_url ||= "/#{plural_resource_name}/#{resource_id}.json"
|
49
|
+
HTTP.delete(destroy_resource_url, payload: index_show_destroy_resource_params(params: params.to_h), &response_handler)
|
50
|
+
end
|
51
|
+
|
52
|
+
def index_show_destroy_resource_params(params: nil)
|
53
|
+
{authenticity_token:}.merge(params.to_h)
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_update_resource_params(resource: nil, resource_class: nil, resource_attributes: nil, singular_resource_name: nil, params: nil)
|
57
|
+
resource_class ||= resource&.class
|
58
|
+
singular_resource_name ||= singular_resource_name_for_resource_class(resource_class)
|
59
|
+
resource_params = {authenticity_token:}
|
60
|
+
resource_attributes ||= resource&.to_h&.reject { |attribute, value| TIMESTAMP_ATTRIBUTES.include?(attribute) }
|
61
|
+
resource_params[singular_resource_name] = resource_attributes.to_h
|
62
|
+
resource_params = resource_params.merge(params.to_h)
|
63
|
+
resource_params
|
64
|
+
end
|
65
|
+
|
66
|
+
def authenticity_token
|
67
|
+
Element['meta[name=csrf-token]'].attr('content')
|
68
|
+
end
|
69
|
+
|
70
|
+
def singular_resource_name_for_resource_class(resource_class)
|
71
|
+
return nil if resource_class.nil?
|
72
|
+
resource_class.to_s.split('::').last.downcase
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -328,6 +328,7 @@ files:
|
|
328
328
|
- lib/glimmer/web/event_proxy.rb
|
329
329
|
- lib/glimmer/web/formatting_element_proxy.rb
|
330
330
|
- lib/glimmer/web/listener_proxy.rb
|
331
|
+
- lib/rails/resource_service.rb
|
331
332
|
homepage: http://github.com/AndyObtiva/glimmer-dsl-web
|
332
333
|
licenses:
|
333
334
|
- MIT
|