eksa-framework 0.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/README.md +10 -7
- data/app/controllers/pages_controller.rb +4 -0
- data/app/controllers/seo_controller.rb +31 -0
- data/app/views/docs.html.erb +31 -3
- data/app/views/index.html.erb +1 -1
- data/app/views/kontak.html.erb +31 -0
- data/app/views/layout.html.erb +23 -5
- data/config.ru +5 -0
- data/db/eksa_app.db +0 -0
- data/lib/eksa/version.rb +1 -1
- data/lib/eksa.rb +12 -10
- metadata +17 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eac9fa3b3a99369457c3dbbda0ea70f15d0f6a7c52aa0e53c64012d78746790d
|
|
4
|
+
data.tar.gz: 3579652838460c2b91b6945ee9b54418009d18d9215bf8e87aae88545cd1eea8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 46f87ef4e149ed0517512fd9394dfae71347cf3f9628630146da98d9e0b82435c92a487e3aaff354e650ba7b1aaecc1e9a658253004de584d7727d7d1e83e4c8
|
|
7
|
+
data.tar.gz: 3a5390e386e690d3bc2d695c1c645d70105d99949a29be3d077ddded8b99ce1375fdcf93df6196837edfeed69164d6ce6106069fee9a5575faec6ae91847c7b1
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -10,12 +10,15 @@
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
## 🚀 Fitur Unggulan
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
|
|
14
|
+
* 💎 **Modern Glassmorphism UI**: Tampilan transparan yang indah dengan Tailwind CSS & Lucide Icons.
|
|
15
|
+
* ⚡ **Rack 3 Ready**: Menggunakan standar terbaru dengan penanganan header modern.
|
|
16
|
+
* 🛠️ **CLI Generator**: Siapkan struktur project instan dengan perintah `eksa-init`.
|
|
17
|
+
* 💾 **Auto-Migration DB**: Database SQLite otomatis dibuat saat server pertama kali dijalankan.
|
|
18
|
+
* 🔔 **Flash Messages**: Notifikasi animasi elegan yang kompatibel dengan cookie Rack 3.
|
|
19
|
+
* 🛤️ **Simple Routing**: Sistem routing yang eksplisit dan mudah dikelola di `config.ru`.
|
|
20
|
+
* 🔍 **Dynamic SEO Engine**: Penanganan otomatis file `robots.txt` dan `sitemap.xml` yang adaptif terhadap rute aplikasi.
|
|
21
|
+
* 🧩 **Smart Response Handling**: Framework kini mampu mendeteksi dan mengeksekusi array respons Rack manual untuk konten non-HTML (XML/Plain Text).
|
|
19
22
|
|
|
20
23
|
---
|
|
21
24
|
|
|
@@ -102,4 +105,4 @@ Eksa menggunakan **Tailwind CSS** dan **Animate.css**. Anda dapat mengatur efek
|
|
|
102
105
|
|
|
103
106
|
## 📜 Lisensi
|
|
104
107
|
|
|
105
|
-
Proyek ini dilisensikan di bawah **MIT License**. Lihat file [LICENSE](
|
|
108
|
+
Proyek ini dilisensikan di bawah **MIT License**. Lihat file [LICENSE](LICENSE) untuk detail lebih lanjut.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class SeoController < Eksa::Controller
|
|
2
|
+
def robots
|
|
3
|
+
content = <<~TEXT
|
|
4
|
+
User-agent: *
|
|
5
|
+
Allow: /
|
|
6
|
+
Disallow: /hapus
|
|
7
|
+
Disallow: /edit
|
|
8
|
+
|
|
9
|
+
Sitemap: https://#{request.host}/sitemap.xml
|
|
10
|
+
TEXT
|
|
11
|
+
[200, { "Content-Type" => "text/plain" }, [content]]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def sitemap
|
|
15
|
+
lastmod = Time.now.strftime("%Y-%m-%d")
|
|
16
|
+
|
|
17
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
|
18
|
+
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
|
|
19
|
+
|
|
20
|
+
["/", "/about", "/docs", "/kontak"].each do |path|
|
|
21
|
+
xml += "<url>"
|
|
22
|
+
xml += "<loc>https://#{request.host}#{path}</loc>"
|
|
23
|
+
xml += "<lastmod>#{lastmod}</lastmod>"
|
|
24
|
+
xml += "<priority>0.8</priority>"
|
|
25
|
+
xml += "</url>"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
xml += '</urlset>'
|
|
29
|
+
[200, { "Content-Type" => "application/xml" }, [xml]]
|
|
30
|
+
end
|
|
31
|
+
end
|
data/app/views/docs.html.erb
CHANGED
|
@@ -39,20 +39,48 @@
|
|
|
39
39
|
</h2>
|
|
40
40
|
<div class="bg-black/40 rounded-2xl p-6 font-mono text-sm border border-white/10 space-y-3">
|
|
41
41
|
<div>
|
|
42
|
-
<p class="text-white/30"># 1. Install gem
|
|
43
|
-
<p class="text-indigo-300">gem install
|
|
42
|
+
<p class="text-white/30"># 1. Install gem</p>
|
|
43
|
+
<p class="text-indigo-300">gem install eksa-framework</p>
|
|
44
44
|
</div>
|
|
45
45
|
<div>
|
|
46
46
|
<p class="text-white/30"># 2. Inisialisasi project baru</p>
|
|
47
47
|
<p class="text-indigo-300">eksa-init</p>
|
|
48
48
|
</div>
|
|
49
49
|
<div>
|
|
50
|
-
<p class="text-white/30"># 3.
|
|
50
|
+
<p class="text-white/30"># 3. Install dependensi</p>
|
|
51
|
+
<p class="text-indigo-300">bundle install</p>
|
|
52
|
+
</div>
|
|
53
|
+
<div>
|
|
54
|
+
<p class="text-white/30"># 4. Jalankan server</p>
|
|
51
55
|
<p class="text-indigo-300">rackup config.ru</p>
|
|
52
56
|
</div>
|
|
53
57
|
</div>
|
|
54
58
|
</section>
|
|
55
59
|
|
|
60
|
+
<section id="struktur" class="mb-12 scroll-mt-24">
|
|
61
|
+
<h2 class="text-2xl font-bold mb-4 flex items-center gap-2">
|
|
62
|
+
<i data-lucide="folder-tree" class="w-6 h-6 text-indigo-400"></i> Struktur Project
|
|
63
|
+
</h2>
|
|
64
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
65
|
+
<div class="bg-white/5 p-4 rounded-xl border border-white/10">
|
|
66
|
+
<code class="text-indigo-300 font-bold">app/</code>
|
|
67
|
+
<p class="text-xs text-white/50 mt-1">Berisi Controllers, Models, dan Views aplikasi Anda.</p>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="bg-white/5 p-4 rounded-xl border border-white/10">
|
|
70
|
+
<code class="text-indigo-300 font-bold">db/</code>
|
|
71
|
+
<p class="text-xs text-white/50 mt-1">Lokasi penyimpanan database SQLite (Terpisah dari app).</p>
|
|
72
|
+
</div>
|
|
73
|
+
<div class="bg-white/5 p-4 rounded-xl border border-white/10">
|
|
74
|
+
<code class="text-indigo-300 font-bold">lib/eksa/</code>
|
|
75
|
+
<p class="text-xs text-white/50 mt-1">Mesin inti (Core Engine) dari Eksa Framework.</p>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="bg-white/5 p-4 rounded-xl border border-white/10">
|
|
78
|
+
<code class="text-indigo-300 font-bold">exe/</code>
|
|
79
|
+
<p class="text-xs text-white/50 mt-1">Executable files seperti generator <code class="text-indigo-200">eksa-init</code>.</p>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</section>
|
|
83
|
+
|
|
56
84
|
<section id="routing" class="mb-12 scroll-mt-24">
|
|
57
85
|
<h2 class="text-2xl font-bold mb-4 flex items-center gap-2">
|
|
58
86
|
<i data-lucide="git-branch" class="w-6 h-6 text-indigo-400"></i> Routing System
|
data/app/views/index.html.erb
CHANGED
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<p class="text-sm text-white/40 mb-4 italic">Menampilkan hasil pencarian untuk "<%= @keyword %>"</p>
|
|
63
63
|
<% end %>
|
|
64
64
|
|
|
65
|
-
<div class="space-y-4 overflow-y-auto max-h-[
|
|
65
|
+
<div class="space-y-4 overflow-y-auto max-h-[320px] pr-2 custom-scrollbar">
|
|
66
66
|
<% if @semua_pesan.any? %>
|
|
67
67
|
<% @semua_pesan.each do |p| %>
|
|
68
68
|
<div class="bg-white/5 border border-white/10 p-5 rounded-2xl flex justify-between items-start group hover:bg-white/10 transition duration-300 animate__animated animate__fadeInUp">
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<div class="glass rounded-3xl p-8 md:p-12 animate__animated animate__fadeIn max-w-2xl mx-auto">
|
|
2
|
+
<div class="text-center mb-8">
|
|
3
|
+
<div class="inline-p-3 rounded-2xl shadow-lg mb-4 inline-block">
|
|
4
|
+
<i data-lucide="message-circle" class="w-8 h-8 text-white"></i>
|
|
5
|
+
</div>
|
|
6
|
+
<h1 class="text-4xl font-extrabold tracking-tight">Hubungi <span class="text-indigo-300">Kami</span></h1>
|
|
7
|
+
<p class="text-white/60 mt-2">Punya pertanyaan tentang Eksa Framework? Chat kami langsung!</p>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="bg-white/5 border border-white/10 rounded-2xl p-6 text-center">
|
|
11
|
+
<h3 class="text-xl font-bold mb-4">WhatsApp Support</h3>
|
|
12
|
+
<p class="text-sm text-white/50 mb-6">Tim kami tersedia untuk membantu Anda secara real-time melalui WhatsApp.</p>
|
|
13
|
+
|
|
14
|
+
<a href="https://wa.me/62895701060973?text=Halo%20Eksa%20Framework!"
|
|
15
|
+
target="_blank"
|
|
16
|
+
class="inline-flex items-center gap-2 bg-emerald-500 hover:bg-emerald-600 text-white font-bold py-3 px-8 rounded-xl transition shadow-lg shadow-emerald-500/20">
|
|
17
|
+
<i data-lucide="external-link" class="w-5 h-5"></i>
|
|
18
|
+
Mulai Chat Sekarang
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="mt-8 text-center">
|
|
23
|
+
<a href="/" class="text-indigo-300 hover:text-white transition text-sm">
|
|
24
|
+
← Kembali ke Beranda
|
|
25
|
+
</a>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<script>
|
|
30
|
+
lucide.createIcons();
|
|
31
|
+
</script>
|
data/app/views/layout.html.erb
CHANGED
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title
|
|
7
|
-
|
|
6
|
+
<title><%= @title || "Eksa Framework" %></title>
|
|
7
|
+
<meta name="description" content="Framework Ruby Modern dengan sentuhan Glassmorphism">
|
|
8
|
+
<meta name="robots" content="index, follow">
|
|
9
|
+
<link rel="canonical" href="https://<%= request.host %><%= request.path %>">
|
|
10
|
+
<meta property="og:title" content="Eksa Framework">
|
|
11
|
+
<meta property="og:description" content="Membangun web cepat dengan estetika transparan.">
|
|
12
|
+
<meta property="og:type" content="website">
|
|
8
13
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
14
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10
15
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
|
@@ -54,16 +59,28 @@
|
|
|
54
59
|
width: 100%;
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
/* Custom Scrollbar untuk list pesan */
|
|
58
62
|
.custom-scrollbar::-webkit-scrollbar {
|
|
59
63
|
width: 6px;
|
|
60
64
|
}
|
|
65
|
+
|
|
61
66
|
.custom-scrollbar::-webkit-scrollbar-track {
|
|
62
|
-
background: rgba(255, 255, 255, 0.
|
|
67
|
+
background: rgba(255, 255, 255, 0.02);
|
|
68
|
+
border-radius: 10px;
|
|
63
69
|
}
|
|
70
|
+
|
|
64
71
|
.custom-scrollbar::-webkit-scrollbar-thumb {
|
|
65
|
-
background: rgba(
|
|
72
|
+
background: rgba(99, 102, 241, 0.2);
|
|
66
73
|
border-radius: 10px;
|
|
74
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
|
78
|
+
background: rgba(99, 102, 241, 0.5);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.custom-scrollbar {
|
|
82
|
+
scrollbar-width: thin;
|
|
83
|
+
scrollbar-color: rgba(99, 102, 241, 0.2) rgba(255, 255, 255, 0.02);
|
|
67
84
|
}
|
|
68
85
|
</style>
|
|
69
86
|
</head>
|
|
@@ -104,6 +121,7 @@
|
|
|
104
121
|
<li><a href="/" class="nav-link flex items-center gap-2"><i data-lucide="home" class="w-4 h-4"></i> Home</a></li>
|
|
105
122
|
<li><a href="/about" class="nav-link flex items-center gap-2"><i data-lucide="info" class="w-4 h-4"></i> About</a></li>
|
|
106
123
|
<li><a href="/docs" class="nav-link flex items-center gap-2"><i data-lucide="book-open" class="w-4 h-4"></i> Docs</a></li>
|
|
124
|
+
<li><a href="/kontak" class="nav-link flex items-center gap-2"><i data-lucide="message-circle" class="w-4 h-4"></i> Contact</a></li>
|
|
107
125
|
</ul>
|
|
108
126
|
|
|
109
127
|
<div class="flex items-center gap-4">
|
data/config.ru
CHANGED
|
@@ -4,6 +4,8 @@ require './app/controllers/pages_controller'
|
|
|
4
4
|
use Rack::Static, urls: ["/css", "/img"], root: "public"
|
|
5
5
|
use Rack::ShowExceptions
|
|
6
6
|
|
|
7
|
+
Dir[File.join(__dir__, 'app/controllers/*.rb')].each { |file| require_relative file }
|
|
8
|
+
|
|
7
9
|
app = Eksa::Application.new
|
|
8
10
|
|
|
9
11
|
app.add_route "/", PagesController, :index
|
|
@@ -11,5 +13,8 @@ app.add_route "/hapus", PagesController, :hapus_pesan
|
|
|
11
13
|
app.add_route "/edit", PagesController, :edit
|
|
12
14
|
app.add_route "/about", PagesController, :about
|
|
13
15
|
app.add_route "/docs", PagesController, :docs
|
|
16
|
+
app.add_route "/kontak", PagesController, :kontak
|
|
17
|
+
app.add_route "/robots.txt", SeoController, :robots
|
|
18
|
+
app.add_route "/sitemap.xml", SeoController, :sitemap
|
|
14
19
|
|
|
15
20
|
run app
|
data/db/eksa_app.db
CHANGED
|
Binary file
|
data/lib/eksa/version.rb
CHANGED
data/lib/eksa.rb
CHANGED
|
@@ -21,22 +21,24 @@ module Eksa
|
|
|
21
21
|
if route
|
|
22
22
|
controller_instance = route[:controller].new(request)
|
|
23
23
|
controller_instance.flash[:notice] = flash_message if flash_message
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if controller_instance.status == 302
|
|
30
|
-
response.redirect(controller_instance.redirect_url, 302)
|
|
24
|
+
response_data = controller_instance.send(route[:action])
|
|
25
|
+
if response_data.is_a?(Array) && response_data.size == 3
|
|
26
|
+
status, headers, body = response_data
|
|
27
|
+
response = Rack::Response.new(body, status, headers)
|
|
31
28
|
else
|
|
32
|
-
response.
|
|
33
|
-
|
|
29
|
+
response = Rack::Response.new
|
|
30
|
+
if controller_instance.status == 302
|
|
31
|
+
response.redirect(controller_instance.redirect_url, 302)
|
|
32
|
+
else
|
|
33
|
+
response.write(response_data)
|
|
34
|
+
response['content-type'] = 'text/html'
|
|
35
|
+
end
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
response.delete_cookie('eksa_flash') if flash_message
|
|
37
39
|
response.finish
|
|
38
40
|
else
|
|
39
|
-
[404, { 'content-type' => 'text/html' }, ["<
|
|
41
|
+
[404, { 'content-type' => 'text/html' }, ["<div style='font-family:sans-serif; text-align:center; padding-top:50px;'><h1>404</h1><p>Halaman tidak ditemukan di Eksa Framework.</p></div>"]]
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eksa-framework
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- IshikawaUta
|
|
@@ -51,6 +51,20 @@ dependencies:
|
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '6.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rackup
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '2.3'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '2.3'
|
|
54
68
|
description: Framework MVC ringan dengan tema modern, sistem routing, dan auto-database
|
|
55
69
|
SQLite.
|
|
56
70
|
email:
|
|
@@ -64,11 +78,13 @@ files:
|
|
|
64
78
|
- LICENSE
|
|
65
79
|
- README.md
|
|
66
80
|
- app/controllers/pages_controller.rb
|
|
81
|
+
- app/controllers/seo_controller.rb
|
|
67
82
|
- app/models/pesan.rb
|
|
68
83
|
- app/views/about.html.erb
|
|
69
84
|
- app/views/docs.html.erb
|
|
70
85
|
- app/views/edit.html.erb
|
|
71
86
|
- app/views/index.html.erb
|
|
87
|
+
- app/views/kontak.html.erb
|
|
72
88
|
- app/views/layout.html.erb
|
|
73
89
|
- config.ru
|
|
74
90
|
- db/eksa_app.db
|