Thanks to this gem, we can define hooks in our views and easily extend them. It’s really easy to extend views, as you’re about to see.
But first things first:
git checkout -b Chapter-11
We need to make sure the deface gem is in our engine gemspec.
. . . s.add_dependency "deface", '~> 1.4.0'
If you remember correctly, we need to require this gem in
require "deface" module Blast module Contacts end end
bundle install from the parent app to get Deface and restart the server to load our new gem.
Now, we can start on the interesting stuff.
First, what’s a hook? In Deface terms, it’s an element in your view that you can use to add some code, either before, after, inside and so on. Theory sucks so let’s create a hook right now to understand what it really is!
We’re going to add a hook inside the
Core engine in the layout file.
Locate the piece of code in Listing 3:
<!-- ... --> <ul class="navbar-nav mr-auto"> <li data-blast-hook='main_nav' class="nav-item <%= active(blast.root_path) %>"> <%= link_to 'Dashboard', blast.root_path, class: 'nav-link' %> </li> </ul> <!-- ... -->
Did you notice what we added? Did you see the
With this, we basically defined this list element as a hook. With Deface, we can now add some code before, or after, it very easily. Note that it doesn’t have to be a
data-attribute. It can be literally anything: an ID, a class or any kind of selectable element. To keep the code clean we used a unique
data-attribute with different values. It makes it easy to find your hooks.
Now that we have a hook, we can create an override!
A Deface override is a small piece of code that will detect a hook and insert the code we tell it to. There is actually another way to use Deface, using their custom
DSL, but we prefer the solution we’re going to show you. You can learn more about the other technique on the Deface GitHub page.
If you didn’t see it yet, there is a folder named “overrides” in
blast_crm/engines/contacts/app. It was generated by
modular_engine and will be used to store our overrides.
Let’s create an override file named
add_contacts_link_to_nav.rb and put the contents of Listing 4 inside it (run the command from the
Basically, we’re instantiating the
Deface::Override class with a set of options. Wondering what each option means? The following is from the Deface GitHub page:
The template / partial / layout where the override should take effect eg:
admin/posts/new this will apply to all controller actions that use the specified template.
Unique name for override so it can be identified and modified later. This needs to be unique within the same
Inserts after all elements that match the supplied selector. One of the many options available like
insert_top and so on. Check the documentation for more options!
Relative path to a partial.
Namespace the override to avoid conflicts with other engines.
String containing original markup that is being overridden. If supplied Deface will log when the original markup changes, which helps highlight overrides that need attention when upgrading versions of the source application. Only really warranted for
:replace overrides. NB: All whitespace is stripped before comparison.
These are just the options we’ll be using in this book. Don’t hesitate to check what else you can do and adapt what we’re showing you to match your needs.
Now, let’s see how it looks by navigating to
Oops… We didn’t create the override view that’s supposed to be inserted.
We can create the override view in
app/views/blast/contacts/app/overrides/. The name needs to be the same as the one we defined in the previous step in
:partial. In our case, the file should be named
_contacts_link.html.erb, with the contents of Listing 5:
And after a quick refresh, we get:
Wow, isn’t that great? Feel free to play with it… try removing the
Contacts engine from the
bundle install, restart the server and refresh the page. No contacts link anymore! Now you know how easy it is to extend a view in another engine. Just to be sure, we’ll do it a few more times in the next chapters.
How about we extend some models now?
git add .
git commit -m "Extending Contacts Views"
git push origin Chapter-11
In this chapter we extended the
Core module views so that our
Contacts views are plug-and-playable.
defacegem to allow for extending views using overrides.
In the next chapter we will learn how to extend Models and Controllers.