Closed vajrabisj closed 5 months ago
It is hard to help without being able to look at the actual code.
Could you create a temporary repository with all code you are trying to run?
(defapp tasks :prefix "/")
(defwidget taskw () ((title :initarg :title :accessor title) (done :initarg :done :initform "false" :accessor done)))
(defun make-taskw () (make-instance 'taskw :title "changing the world" :done "false"))
(defmethod render ((task taskw)) "Render a task" (with-html (:span (title task) (format nil "done is") (done task))))
(defroutes tasks-routes ("/tasks/task/" (make-taskw)))
It is hard to help without being able to look at the actual code.
Could you create a temporary repository with all code you are trying to run?
I found there are examples in your doc , maybe you could kindly let me know how to run those examples so I can learn by myself :)
It is hard to help without being able to look at the actual code.
Could you create a temporary repository with all code you are trying to run?
by reviewing your doc example, finally i understood how to use your package :), sorry for disturbing and your package is really great!
That is the reason why the documentation exists!
If you will find a way how it could be improved, please, let me know!
Yes, that’s great. I am exploring your task examples. One think would like to check is how I can get synced task list from different devices, eg after I change the task list from laptop the page on my iPhone could get same result or vice versa…
Thanks in advance.
Regards,
Michael
Alexander Artemenko @.***>于2024年6月7日 周五21:00写道:
That is the reason why the documentation exists!
If you will find a way how it could be improved, please, let me know!
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2154788757, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J4NSTQARLCJ7WX6CDTZGGVGVAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJUG44DQNZVG4 . You are receiving this because you authored the thread.Message ID: @.***>
For doing this, you'll need each client to establish a connection to the server and also you'll need some event bus to push events to all listening widgets. Usually I'm using https://github.com/40ants/reblocks-websocket for the first task and https://github.com/fukamachi/event-emitter.
More simple solution is to have a small JavaScript code, which will call an action and reload your widget if some changes were discovered on the backend. Here is an example of a render method which implements this approach:
(defmethod render ((widget recent-comments-widget))
(flet ((update-widget (&rest args)
(declare (ignore args))
(reblocks/widget:update widget)))
(let* ((delay 1000)
(action-code (fmt "setTimeout(function() {~A}, ~A)"
(reblocks/actions:make-js-action #'update-widget)
delay))
(client (chat/client::connect (make-chat-api)))
(messages (chat/client:get-random-messages client
:limit 5)))
(with-html
(:script
(:raw action-code))
(:div :class "xl:text-3xl text-l my-8"
"Some data to be updated")))))
However it does not check if there were some updates, it refreshes the widget's content every 1 second.
Thx a lot for your prompt reply, it’s helpful!
By learning your reblocks package I found the widget concept is great. One thing I have confuse is if several widgets have to update consequentially how to manage? For example, when :onclick triggered in widget A to show widget B just aside A. In widget A’s render method, it seems not able to pass the instance of widget B to make widget B got updated… any practice to solve this? Thx in advance.
Regards,
Michael
Alexander Artemenko @.***>于2024年6月8日 周六14:50写道:
For doing this, you'll need each client to establish a connection to the server and also you'll need some event bus to push events to all listening widgets. Usually I'm using https://github.com/40ants/reblocks-websocket for the first task and https://github.com/fukamachi/event-emitter.
More simple solution is to have a small JavaScript code, which will call an action and reload your widget if some changes were discovered on the backend. Here is an example of a render method which implements this approach:
(defmethod render ((widget recent-comments-widget)) (flet ((update-widget (&rest args) (declare (ignore args)) (reblocks/widget:update widget))) (let* ((delay 1000) (action-code (fmt "setTimeout(function() {~A}, ~A)" (reblocks/actions:make-js-action #'update-widget) delay)) (client (chat/client::connect (make-chat-api))) (messages (chat/client:get-random-messages client :limit 5)))
(with-html (:script (:raw action-code)) (:div :class "xl:text-3xl text-l my-8" "Some data to be updated")))))
However it does not check if there were some updates, it refreshes the widget's content every 1 second.
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2155842380, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J6OWAMARSE7OEKLSNLZGKSVDAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJVHA2DEMZYGA . You are receiving this because you authored the thread.Message ID: @.***>
I learned a lot from examples in reblocks and other related packages, really great! Thanks for your work!
If I want to put my reblocks app into production, how to make it standalone app so it can run into the system service in Linux. Should I use roswell? Or there is other solution?
Regards,
Michael
@.***>于2024年6月8日 周六17:53写道:
Thx a lot for your prompt reply, it’s helpful!
By learning your reblocks package I found the widget concept is great. One thing I have confuse is if several widgets have to update consequentially how to manage? For example, when :onclick triggered in widget A to show widget B just aside A. In widget A’s render method, it seems not able to pass the instance of widget B to make widget B got updated… any practice to solve this? Thx in advance.
Regards,
Michael
Alexander Artemenko @.***>于2024年6月8日 周六14:50写道:
For doing this, you'll need each client to establish a connection to the server and also you'll need some event bus to push events to all listening widgets. Usually I'm using https://github.com/40ants/reblocks-websocket for the first task and https://github.com/fukamachi/event-emitter.
More simple solution is to have a small JavaScript code, which will call an action and reload your widget if some changes were discovered on the backend. Here is an example of a render method which implements this approach:
(defmethod render ((widget recent-comments-widget)) (flet ((update-widget (&rest args) (declare (ignore args)) (reblocks/widget:update widget))) (let* ((delay 1000) (action-code (fmt "setTimeout(function() {~A}, ~A)" (reblocks/actions:make-js-action #'update-widget) delay)) (client (chat/client::connect (make-chat-api))) (messages (chat/client:get-random-messages client :limit 5)))
(with-html (:script (:raw action-code)) (:div :class "xl:text-3xl text-l my-8" "Some data to be updated")))))
However it does not check if there were some updates, it refreshes the widget's content every 1 second.
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2155842380, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J6OWAMARSE7OEKLSNLZGKSVDAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJVHA2DEMZYGA . You are receiving this because you authored the thread.Message ID: @.***>
The easiest way is to use roswell. Usually I'm create a script like this one: https://github.com/ultralisp/ultralisp/blob/master/roswell/ultralisp-server.ros
Or you can use asdf:make.
I've described both ways in this video: https://www.youtube.com/watch?v=_V6cpOtP9e8
Usually I make my server to take all configuration parameters from unix environment, which makes it easy to pass these args from systemd or docker. Just use UIOP:GETENV function to retrieve a setting.
thx, this is helpful and really thanks for your reply.
Regards,
Michael
Alexander Artemenko @.***>于2024年6月10日 周一16:40写道:
The easiest way is to use roswell. Usually I'm create a script like this one: https://github.com/ultralisp/ultralisp/blob/master/roswell/ultralisp-server.ros
Or you can use asdf:make.
I've described both ways in this video: https://www.youtube.com/watch?v=_V6cpOtP9e8
Usually I make my server to take all configuration parameters from unix environment, which makes it easy to pass these args from systemd or docker. Just use UIOP:GETENV function to retrieve a setting.
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2157720996, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J55EGDS3KKLIUM2DLTZGVQ6LAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJXG4ZDAOJZGY . You are receiving this because you authored the thread.Message ID: @.***>
I added the following code to the end of my tasks.lisp file:
(handler-case (bordeaux-threads:join-thread (find-if (lambda (th) (search "hunchentoot" (bordeaux-threads:thread-name th))) (bordeaux-threads:all-threads))))
And use “clackup tasks.lisp” to launch the app, everything’s fine.
But, when I put the clackup command line into systemd file and start it, you know what, strange things happened, I can successfully launch the webapp which has three routes, one of them is from your task list example. But only other two routes could be reached, the task list route got an error, but the whole web app is still running…
I don’t know why after put it to systemd got such error, whether it related to the code I posted at the beginning…
Regards,
Michael
Alexander Artemenko @.***>于2024年6月10日 周一16:40写道:
The easiest way is to use roswell. Usually I'm create a script like this one: https://github.com/ultralisp/ultralisp/blob/master/roswell/ultralisp-server.ros
Or you can use asdf:make.
I've described both ways in this video: https://www.youtube.com/watch?v=_V6cpOtP9e8
Usually I make my server to take all configuration parameters from unix environment, which makes it easy to pass these args from systemd or docker. Just use UIOP:GETENV function to retrieve a setting.
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2157720996, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J55EGDS3KKLIUM2DLTZGVQ6LAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJXG4ZDAOJZGY . You are receiving this because you authored the thread.Message ID: @.***>
Probable reasons why a program running under systemd might fail:
Hi, it’s me again :)
I am modifying your task example:) and plan to add a confirmation before proceeding task deletion, code as following:
(:input :type "submit" :class "button" :value "Delete" ;; Using make-js-handler to integrate Parenscript for confirmation dialog :onclick (reblocks-parenscript:make-js-handler :lisp-code ((&key confirmed) (when confirmed (del-task task))) :js-code ((event) (let ((confirmed (confirm "Are you sure you want to delete this task?"))) (parenscript:create :confirmed confirmed))))))
After running, I got an error of “unknown keywords :Action”, when I select ignore all unknown keywords, the deletion processed successfully. I cannot find the error, maybe in the js-code part? Thx in advance.
Regards,
Michael
Alexander Artemenko @.***>于2024年6月11日 周二16:26写道:
Probable reasons why a program running under systemd might fail:
- it's working dir is different
- it is runnings under another user (probably root)
- environment variables are different – you have to specify them in the systemd config.
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2160104183, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J4DIMYLTK7WDAVSTI3ZG2YDNAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRQGEYDIMJYGM . You are receiving this because you authored the thread.Message ID: @.***>
Change (&key confirmed)
to (&key confirmed &allow-other-keys)
Yes, got it ! Thx for your prompt reply on my silly questions:)
Regards,
Michael
Alexander Artemenko @.***>于2024年6月14日 周五18:36写道:
Change (&key confirmed) to (&key confirmed &allow-other-keys)
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2167745004, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J2ISO7YIZPULF6FRYDZHLBTZAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRXG42DKMBQGQ . You are receiving this because you authored the thread.Message ID: @.***>
Actually, you might expand reblocks-parenscript:make-js-handler form using SLIME/SLY to see the functions it creates for handling events.
Hi, just curious that Is it possible to use CLOG package in reblocks?
Regards,
Michael
Alexander Artemenko @.***>于2024年6月14日 周五19:10写道:
Actually, you might expand reblocks-parenscript:make-js-handler form using SLIME/SLY to see the functions it creates for handling events.
— Reply to this email directly, view it on GitHub https://github.com/40ants/reblocks/issues/56#issuecomment-2167797498, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHAV3J7D7ABME5H3UL33M4DZHLFTFAVCNFSM6AAAAABI4SHNNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRXG44TONBZHA . You are receiving this because you authored the thread.Message ID: @.***>
I've never tried. In my opinion these frameworks are for different kind of tasks: reblocks is closer to traditional sites whereas CLOG tries to implement a desktop-like interface, but in the browser.
Theoretically, there should be a way to combine them, but I don't see any practical use case.
i tried many times, but i only can get page rendered through the init-page method....
i followed the quickstart guide, having: defwidget task, then constructor make-task, then render (task), and then (defroutes tasks-routes ("/tasks/" (make-task-list)) ("/tasks/task/" (make-task)))
the page only showed contents in the init-page function, those contents in the render method never showed...
need guidance...thanks.