Closed lolmaus closed 6 years ago
This would probably better belong in https://github.com/middleman/middleman-livereload
Edit: Realized this is a just reload issue, not live-reload. Carry on...
I'm seeing the same thing too. I tried middleman server --reload-paths=helpers
, but that doesn't seem to cause changes to the helpers to be reloaded.
I was curious if anyone might know a way for changes to /helpers to get picked up when running locally.
Yeah, middleman is already watching helpers, so adding it as a CLI argument won't help.
Gotcha. Just to make sure I understand, when you say that it's watching helpers, does that mean that when a helper's code changes, it would get picked up without restarting the middleman server?
I wasn't sure if that was the expected behavior or if my expectations were out of alignment with reality. Or perhaps I don't have something configured correctly. Or maybe a pull request might help.
Oh - and I also noticed that there's more than one way to setup helpers. I'm referring to using modules approach referred to at the bottom of this page:
http://middlemanapp.com/basics/helpers/#toc_9
Thanks for the help!
Middleman is capable of noticing that helpers files were changed, but it's unable to make use of those changes without full restart.
Definitely a bug.
I'm seeing the same thing. To clarify I don't necessarily need live-reload for my custom helpers. Just having them update on a page reload would be really helpful.
Actually it'd be really handy to reload arbitrary ruby classes that I've manually included, but I understand that might be a bit out of scope.
Actually it'd be really handy to reload arbitrary ruby classes that I've manually included
Same problem here.
I'm using some Ruby libs that I placed in lib
to create content in middleman templates.
I was expecting a rails-like behavior (to reload changed files), because it recognizes the changes in the files:
== The Middleman is reloading
== The Middleman has reloaded
But it seems that it does not reload the files (needs server restart).
The stuff Rails does to make this work is insane black magic. We don't do that (yet).
Well, it seems that you already bundle the Padrino Reloader (which is able to reload Ruby files), but it is not used.
Is there a workaround for this? I can't upgrade to v4 because of #1380
Edit Rebased @themindoverall's patch over v3.3.6
gem "middleman", github: 'joallard/middleman', branch: 'reload_helpers'
This should be working on the official stable version.
I am still having problems with helpers reloading properly with v3.4.0
helpers/
Does the command line messaging show that "middleman is reloading"?
Does the command line messaging show that "middleman is reloading"?
Yeah.
... does is ever say it "has reloaded"?
Yes. It's very easy to reproduce given the steps I've listed on both 3.4.0 and 4.0.0.rc1.
The html reloads fine, but the helper code in /helpers
does not reload.
In the meantime, this is a very crude way to reload middleman when any ruby changes. (There are probably more elegant ways to do this, but it's what I ended up getting working)
# in the Gemfile
group :development do
gem "god"
gem "guard"
end
# in a new file named: middleman.god
# this will start middleman
God.watch do |w|
w.name = "middleman"
w.start = "bundle exec middleman server"
w.keepalive
w.log = "#{File.expand_path("..", __FILE__)}/middleman.log"
w.dir = File.expand_path("..", __FILE__)
end
# in a new file named: Guardfile
# this watches for any ruby changes and tells god to restart middleman
# it would be nice to do this all with Guard, but I don't know enough about managing daemons in Guard
require 'guard/plugin'
module ::Guard
class God < Plugin
def reload
reload_god
end
def run_on_additions(paths)
reload_god
end
def run_on_modifications(paths)
reload_god
end
def run_on_removals(paths)
reload_god
end
private
def reload_god
`god restart`
end
end
end
guard 'God' do
watch(%r{^.+\.rb$})
end
# start god first
$ god -c middleman.god
# then start guard
$ guard -i # you should be good to go at this point
# If you want to close down, CTRL-C guard and then run:
$ god terminate
You can also use guard-middleman which will rebuild the actual html every time something changes, but I just wanted to stick with the ruby server for now.
This is also handy because it will restart whenever lib/
changes
@tdreyno Seem to be facing this issue still in 4.1.1. It says it reloads, but manual refreshes still show old code. Not sure if it helps, but get this message when trying to reload most times:
middleman.1 | /Library/Ruby/Gems/2.0.0/gems/middleman-livereload-3.4.6/lib/middleman-livereload/reactor.rb:14: warning: toplevel constant Mutex referenced by Thread::Mutex
Unfortunately, Ruby's require
only reads the file the first time. There are ways to hack around this, but they are very invasive.
Are you requiring the files in helpers/
or is Middleman automatically doing that?
Hey @tdreyno,
I'm letting Middleman automatically pull them in; following the example in the docs, careers_helpers.rb
has a module CareersHelpers
definition.
Okay, I might be able to hack it in there :) Let me think about it.
Cool - thanks for taking another look!
I would love it if this issue were one day patched in both 3 and 4.
This is still an open issue on the most recent version of Middleman
No solution yet?
As @tdreyno wrote, require
only reads files the first time. However, there is load
, which just loads that file each time you call it.
Since config.rb
is re-evaluated each time Middleman reboots, this will successfully reload helpers:
# in config.rb:
# Middleman fails to reload helpers, although it notices their modification
# This force-reloads them
Dir['helpers/*'].each(&method(:load))
If you have nested helpers, you need to adapt the glob string to something like 'helpers/**/*'
.
This was a game changer for me. Thank you so much!
@tdreyno would it be unreasonable to add the blob from https://github.com/middleman/middleman/issues/1105#issuecomment-305715209 into: https://github.com/middleman/middleman-templates-default/blob/master/template/config.rb (as a comment)? (I'm happy to provide a PR if it's welcome)
I have completely missed the previous answer. Will the hack above apply also to Classes / Extensions?
What if I have something like class SeoSupport < Middleman::Extension
in the helpers folder and the following in the config.rb file?
require "helpers/seo"
activate :seo_support
In fact, also in the attempt to learn, I have created some classes (like the above) and some "wild" methods in individual files whose first line is method thisandthat
. The latter however are never recalled with the require method.
Am I missing something? @tdreyno
@jsoref I replaced require
with load
in our internal code and added some tests. It seems to work in the base case.
Still not sure how I have to reference my routines though.
@andreamoro In that case, I think you should switch require
to load
and place the file in lib
. Helpers are specific to template helper methods and require a specific form (an exported module and pure methods)
@tdreyno ok, if for the classes I've to use a different way (do I need to create a lib folder, where?), Considering the helpers method are just within the helpers subfolder I'm literally missing where and when I should change the require to load.
Can you please give me more hints?
I would suggest always using load
if you want their contents to reload on change. Ruby's require
caches files, which we can't really control.
You can create a lib
folder as a sibling to helpers
. Those are the two paths watched by default for .rb
file changes. The only difference is that there is a little additional processing that happens for files in helpers
to inject their methods into the template context.
So, unless I'm mistaken, by creating a lib folder and moving all class files into it sound suffice. Correct?
When i edit a helper under
/helpers/
, Middleman says:But changes in the helper are not applied. I have to restart Middleman manually every time i edit a helper.
Tested on Windows.