eksa-framework 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e85ac2ace3fdb1fe6b2c408d94bff58d42b679f7a7a12b0912fb7cbe2ce5bd0c
4
- data.tar.gz: ce85c89cb29c1f578c25f13b5e92bb5b6018a5247369c95952b5d870a4fec763
3
+ metadata.gz: eac9fa3b3a99369457c3dbbda0ea70f15d0f6a7c52aa0e53c64012d78746790d
4
+ data.tar.gz: 3579652838460c2b91b6945ee9b54418009d18d9215bf8e87aae88545cd1eea8
5
5
  SHA512:
6
- metadata.gz: e51d72fa4f75e91045950a2d9b3224d0ee65d340675cc0149b38cc00127a75e9148d78b10b34ac11a088a0a121d0cb14098c78b3f6c984a5128448299ab3fe33
7
- data.tar.gz: 26e151869a5e473589101ce53f74b70a704efa6a8304400c8970af9650f9502c89fcd3da0e3c2c5f33a28a3da22bec794234b5a1d0236281aae35ab05a15af5a
6
+ metadata.gz: 46f87ef4e149ed0517512fd9394dfae71347cf3f9628630146da98d9e0b82435c92a487e3aaff354e650ba7b1aaecc1e9a658253004de584d7727d7d1e83e4c8
7
+ data.tar.gz: 3a5390e386e690d3bc2d695c1c645d70105d99949a29be3d077ddded8b99ce1375fdcf93df6196837edfeed69164d6ce6106069fee9a5575faec6ae91847c7b1
data/README.md CHANGED
@@ -10,12 +10,15 @@
10
10
  ---
11
11
 
12
12
  ## 🚀 Fitur Unggulan
13
- - 💎 **Modern Glassmorphism UI**: Tampilan transparan yang indah dengan Tailwind CSS & Lucide Icons.
14
- - **Rack 3 Ready**: Menggunakan standar terbaru dengan penanganan header modern.
15
- - 🛠️ **CLI Generator**: Siapkan struktur project instan dengan perintah `eksa-init`.
16
- - 💾 **Auto-Migration DB**: Database SQLite otomatis dibuat saat server pertama kali dijalankan.
17
- - 🔔 **Flash Messages**: Notifikasi animasi elegan yang kompatibel dengan cookie Rack 3.
18
- - 🛤️ **Simple Routing**: Sistem routing yang eksplisit dan mudah dikelola di `config.ru`.
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
 
@@ -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
@@ -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 secara lokal</p>
43
- <p class="text-indigo-300">gem install ./eksa-framework-0.1.0.gem</p>
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. Jalankan server</p>
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
@@ -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-[500px] pr-2 custom-scrollbar">
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">
@@ -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>Eksa Framework | Modern Ruby Development</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.05);
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(255, 255, 255, 0.2);
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,7 +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>
107
- <li><a href="/kontak" class="nav-link flex items-center gap-2"><i data-lucide="message-circle" class="w-4 h-4"></i> Kontak</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>
108
125
  </ul>
109
126
 
110
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
@@ -12,5 +14,7 @@ app.add_route "/edit", PagesController, :edit
12
14
  app.add_route "/about", PagesController, :about
13
15
  app.add_route "/docs", PagesController, :docs
14
16
  app.add_route "/kontak", PagesController, :kontak
17
+ app.add_route "/robots.txt", SeoController, :robots
18
+ app.add_route "/sitemap.xml", SeoController, :sitemap
15
19
 
16
20
  run app
data/db/eksa_app.db CHANGED
Binary file
data/lib/eksa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eksa
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
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
- response_body = controller_instance.send(route[:action])
26
-
27
- response = Rack::Response.new
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.write(response_body)
33
- response['content-type'] = 'text/html'
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' }, ["<h1>404 - Not Found</h1>"]]
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: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - IshikawaUta
@@ -78,6 +78,7 @@ files:
78
78
  - LICENSE
79
79
  - README.md
80
80
  - app/controllers/pages_controller.rb
81
+ - app/controllers/seo_controller.rb
81
82
  - app/models/pesan.rb
82
83
  - app/views/about.html.erb
83
84
  - app/views/docs.html.erb