the singularity of being and nothingness
Virtual Directory-Driven ExtJS 4 Development – The Finale
If you’ve been following along the last few posts, you’ve seen how it’s relatively simple to set up your local development environment to leverage global library assets to create ExtJS 4 applications. What you’ve probably also noticed is that there are a number of configurations (some one-time, others per-application) that need to be implemented before it will work. While these are not necessarily that big of a deal (especially in light of the benefits you gain), it’s still a lot. Here’s the full list:
- Generate application with Sencha Cmd
- Add virtual directories (ExtJS library, global plugins, and resources)
- Update ext.dir in /app/.sencha/workspace/sencha.cfg
- Add workspace.classpath in /app/.sencha/workspace/sencha.cfg
- Add full host path to /app/resources/theme/{themename}/theme.html
- Update $ext_path in /app/resources/sass/{themename}/config.rb
- Add fixes to /extroot/resources/themes/lib/Utils.rb (one time)
- Update /app/.sencha/app/build.impl.xml to copy theme images to app folder
- Develop application
- Build application and theme
So only 9 per-app steps…not too bad. But wouldn’t it be WAY better if this number could drastically reduced?
WARNING!! WARNING!! WARNING!!
What follows is a total hack. The steps outlined will show you how to modify your Sencha Cmd installation so that the configurations previously outlined will now be the “default”. These changes apply only to ExtJS 4 app creation and compile/build. I didn’t bother with the more advanced commands in Sencha Cmd, nor with anything relating to Sencha Touch.
Finally, any changes you make are on you. This is merely a proof-of-concept; I’m not suggesting that you do this, nor that this is a best practice. It’s also not future-proof, so if you do make these changes and install a newer release of Sencha Cmd, the newer version will not have these changes.
At the time of this writing, I’m using Sencha Cmd 3.0.0.250.
The Beauty of Templating
One of the really great things about how Sencha Cmd creates applications is that it uses a pretty nifty templating system. Consider a simple file like /app/resources/sass/default/config.rb:
# Get the directory that this configuration file exists in dir = File.dirname(__FILE__) $ext_path = '/Users/existdissolve/sencha/extjs/ext-4.1.1a' # Load the extjs framework automatically. load File.join($ext_path, 'resources', 'themes') # Compass configurations sass_path = dir css_path = File.join("..", "..", "css", "default") images_dir = File.join("..", "..", "images", "default") output_style = :compressed environment = :production
This file is not created out of mid-air; rather, it is the result of the dynamic creation of the file based on the collusion of configuration data AND a static template file. If you look in /Users/{username}/bin/Sencha/Cmd/3.0.0.250/plugins/ext/current/templates/App/resources/sass/{themeName}/, you’ll find a file called config.rb.tpl.default. Open this up, and here’s what you’ll see:
# Get the directory that this configuration file exists in dir = File.dirname(__FILE__) $ext_path = File.join('..', '..', '..', '{frameworkPath}') # Load the extjs framework automatically. load File.join($ext_path, 'resources', 'themes') # Compass configurations sass_path = dir css_path = File.join("..", "..", "css", "{themeName}") images_dir = File.join("..", "..", "images", "{themeName}") output_style = :compressed environment = :production
As you can see, this file is EXACTLY the same as our generated file, the only difference being the $ext_path. In the template file, this value is merely a placeholder for a variable which will be replaced with the context-specific value when the app generation occurs.
At this point, you’re probably thinking that given this “templating”, the approach I’m talking about will be to modify these templates with different values that will be used to eliminate the later configuration that would have to be done if we simply used the stock implementation. You would be thinking correctly. Let’s get started.
Prepare Sencha Cmd
You can do as you’d like, but before we start I’m going to suggest that you make a copy of your latest installation of Sencha Cmd, and use that as the one which we modify for our purposes. For this walkthrough, I’m calling my copy 3.0.0.251.
Once you’ve copied the installation and renamed it, we now need to let Terminal know how to find it. We’ll do that by updating the PATH variable:
PATH=$PATH:/Users/{username}/bin/Sencha/Cmd/3.0.0.251 export PATH
Next, go into the 3.0.0.251 folder, and rename sencha-3.0.0.250 to sencha-3.0.0.251
Then, in the same folder, open sencha.cfg and update the cmd.version to the correct value.
Now if you open a new Terminal session, you should be able to type
sencha-3.0.0.251
and see the standard listing of Sencha Cmd commands, along with the correct version number.
Nice. This means our “copy” is working. We can now start breaking stuff.
NOTE: For the following, all modifications will be occurring within the /Users/{username}/bin/Sencha/Cmd/3.0.0.251 folder, unless otherwise specified.
Also, in order to generate and build apps within our new version of Sencha Cmd, we’ll need to use the endpoint sencha-3.0.0.251 when running commands (e.g., sencha-3.0.0.251 app build)
Fix Non-Hostname Accessible Theme.html
Remember the issue I outlined earlier in our theme.html with the path to the ext-all.js file not being accessible when using virtual directories? Let’s fix that.
Open theme.html.tpl.default, located at:
/plugins/ext/current/templates/App/resources/theme/{themeName}/
On line 11 (or so), change it from:
<script type="text/javascript" src="../../../{frameworkPath}/ext-all.js"></script>
to:
<script type="text/javascript" src="http://cdn.sencha.io/ext-4.1.1-gpl/ext-all.js"></script>
NOTE: You can also specify another host path, if you have one set up (e.g., dev.assets.com)
With this fixed, our theme.html file will properly find our assets, regardless of whether we are viewing it via our hostname, or compiling the theme via Sencha Cmd.
Full ExtJS Path in SASS Config
The next change we need to make is to replace the relative path set for the ExtJS library in our SASS config.rb file. Since we’re using a virtual directory for development, the compilation process will not know how to find the library with a relative path, so we need to specify the full path.
Open config.rb.tpl.default, located at:
plugins/ext/current/templates/App/resources/sass/{themeName}/
On line 3 (or so), change it from:
$ext_path = File.join('..', '..', '..', '{frameworkPath}')
to:
$ext_path = '{frameworkDir}'
Workspace Config
In the first post on this subject, I showed how we need to update the sencha.cfg file in /app/.sencha/workspace/. We do this in order to let the compiler know where to find the ExtJS library (since it doesn’t know about virtual directories). One of the steps in this process was to define the workspace.classpath variable to point to our global, custom code path. Let’s go ahead and do that now so it will be a part of the default code generated with a new app.
Open sencha.cfg.tpl.default, located at:
/templates/workspace/{senchadir}/workspace/
On a new line at the end of the file, enter:
workspace.classpath=/Users/{username}/sencha/extjs/ux
(Or whatever the path to your common, custom code folder is)
Now, if you’re paying really close attention, you may remember that we made another change to this file. Specifically, we defined the value of ext.dir to be:
/Users/{username}/sencha/extjs/ext-4.1.1a
You can add that now, but it will end up getting overwritten (I’ll explain later). For now, just make the custom code path change, and let’s move on.
Copy Theme Images
If you remember from the last post, one problem we had with building our theme was that the core theme images were in a virtual directory, and so were not getting included in the build process. In this step, we’ll actually add a bit of ANT script to manually copy the files we want to the appropriate location.
Open build-impl.xml, located at:
/plugins/ext/current/templates/App/.sencha/app
On line 219 (after the image slicing), add the following:
<!-- get theme images from root extjs source --> <copy todir="${build.dir}/resources/images/"> <fileset dir="${ext.dir}/resources/themes/images/" includes="${theme.name}/**/*"/> </copy>
Delete Local Ext Directory and Other Cleanup
This one’s fun. If you recall, our entire point of pursuing this course throughout the last 3 posts is to be able to use a common, centralized ExtJS library for development, instead of making a copy of the entire library for each app (which is the default behavior).
It turns out that there are a bunch of parts of the app generation process that depend upon the ext folder existing locally, at least for the duration of the app creation. So instead of refactoring all those dependencies, I took the lazy route: I simply delete the locally-created copy after the process is complete.
This is pretty simple to do with ANT. First, open plugin.xml, located at:
/plugins/ext/current/
Now, we need to add a new “target”, whose specified tasks will be executed. Sencha Cmd exposes a number of these, and handily there is one that fits perfectly for our need: -after-generate-app.
Here’s what my -after-generate-app target looks like:
<target name="-after-generate-app"> <delete includeemptydirs="true"> <fileset dir="${args.path}/ext" defaultexcludes="false"> </fileset> </delete> <!--rewrite sencha.cfg ext.dir for build of non-relative paths--> <propertyfile file="${args.path}/${senchadir}/workspace/sencha.cfg"> <entry type="string" operation="=" key="${framework.name}.dir" value="${framework.dir}"/> </propertyfile> </target>
Two things happening here.
First, we have a delete task. We simply give it the correct path, and it will take care of deleting the appropriate directories/files. Nice.
Second, remember the ext.dir variable in the sencha.cfg.tpl.default? Now that we’ve generated the app, we can use the propertyfile task to update our key/value pair line in that file.
Ok, that’s done. Since we have this file open, go ahead and go to line 93 (or so) and add the following:
<param name="frameworkDir" value="${framework.dir}"/>
We need this variable exposed elsewhere, so let’s get it done now.
Wrapping Up
That’s it! Nothing more to do now other than to start developing. But before we do, let’s see how much repetition we’ve eliminated:
- Generate application with Sencha Cmd
- Add virtual directories (ExtJS library, global plugins, and resources)
Update ext.dir in /app/.sencha/workspace/sencha.cfgAdd workspace.classpath in /app/.sencha/workspace/sencha.cfgAdd full host path to /app/resources/theme/{themename}/theme.htmlUpdate $ext_path in /app/resources/sass/{themename}/config.rbAdd fixes to /extroot/resources/themes/lib/Utils.rb (one time)Update /app/.sencha/app/build.impl.xml to copy theme images to app folder- Develop application
- Build application and theme
Awesome! Obviously, we still have to generate the app and add some virtual directories. But beyond that, our modifications of Sencha Cmd have obviated the need for any post-generate build-related configuration. Since our templates now reflect our virtual-directory-centric approach, all we have to worry about is developing awesome ExtJS applications!
Print article | This entry was posted by existdissolve on November 24, 2012 at 7:59 am, and is filed under ExtJS, JavaScript. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |