Visual Studio Code - Dealing with Expression Web's Metadata

October 10, 2020 - Expression Web Tip #1

Visual Studio Code TipFrom the outset FrontPage needed to keep track of metadata, or information about the Web site it was being used to build. Vermeer Technologies, Inc., the inventor of FrontPage, decided to keep such data in a suite of "ghost" files, one for every file in the site. This was accomplished by putting a folder in every folder of the site into which the ghost files were stored. For example, if the file /products/wrench.html existed, so would the file /products/_vti_cnf/wrench.html. For clarity, I will refer to these as the VTI files.

Why "VTI?" The metadata folders were named for the company and Microsoft retained the naming convention through all versions of Expression Web (EW).

The VTI files are necessary for Expression Web when dealing with static Web sites and especially when using dynamic Web templates (DWTs). For Visual Studio Code (VSC), they mean nothing. They are just overhead.

There are three ways of dealing with the VTI files.

The first is to tell EW not to use them. This is done in Site | Site Settings by unchecking the box shown below:

Confirmation is required:

When this is done, EW will no longer be able to handle DWTs. If needed, the metadata can be restored by going back into Site Settings and checking the box. Again, confirmation is required:

I do not entirely trust this alone, so I take one more step. On EW's menu under Tools | Recalculate Hyperlinks I run that process. This feature was originally intended to reconcile URLs when they got out of sync (EW is not perfect in handling metadata) but that involved touching the metadata anyway. This is one of those features that is not documented by EW.

The next option is deleting the metadata files manually. Fourteen years ago I wrote a Visual Basic utility that stripped them all out and there was a FrontPage utility that did the same thing. I'm sure a PowerShell script would suffice. These are good solutions if EW will no longer be used.

The other is having VSC ignore them. If possible, it means they can be left in place for use with EW if necessary but otherwise do not introduce any overhead with VSC.

My preference is to delete the files manually but I do use EW's tools when I need to restore the metadata for DWT purposes. At the same time, I also have VSC ignore them.

Understanding Settings in Visual Studio Code

Before explaining how to exclude files in VSC, it is important to understand that there are two major spaces for settings. One is called "User" and the other "Workspace." In the most general sense, User means "global" and Workspace means "local." User settings affect VSC as a whole, meaning that they will apply to whatever project is being edited. Workspace settings apply to the specific project being edited. Settings can be viewed by selecting File | Preferences | Settings, by opening the command palette with the shortcut Ctrl+Shift+P and searching for "settings," or by the shortcut Ctrl+, (that's Ctrl plus comma). This is what you will see:

Visual Studio Code Settings

There are two selections near the top, User and Workspace. No matter where the settings are coming from, they will be visible here.

That last sentence deserves explanation because it is extremely important. When necessary, VSC will add a folder at the root named ".vscode" that is used to hold workspace-specific information. Such information is usually stored in JSON files.

Visual Studio Code File Exclusions

VSC natively includes an exclusion mechanism for files. This can be found by opening settings and searching for "exclude." This is what you get:

Because User is selected (just under the search box), the Files: Exclude setting shows VSC's global list of exclusions. This list can be changed by clicking the Add Pattern button, which will add new global exclusions. My preference is to leave the setting defaults alone and change only the local, workspace settings. Looking closely above, you can see the legend Modified in: Workspace. Clicking the Workspace tab at the top, the display changes to this:

Now the VTI files are listed in the exclusion list along with VSC's default exclusions. These new additions can be entered manually by clicking the Add Pattern button or a settings.json file can be created in the .vscode folder. That is my preference. Here's what my JSON file looks like:

{
    "files.exclude": {
        "**/_vti_cnf/**": true,
        "**/_vti_pvt/**": true
    }
}

An excellent VSC feature is that any time any setting is changed, it is instantly applied. Creating and saving /.vscode/settings.json causes all the VTI files to vanish from the explorer. They are not deleted; they are just not visible in the editor.

The "glob patterns" (shown above in the yellow box) tell VSC to look for any occurrence of any folder matching "/_vti_cnf" or "_vti_pvt". It is a recursive pattern, meaning that it examines all sub-folders to find matches.

You'll also notice that my JSON file only mentions those patterns in which I have an interest. Yet when you examine the settings in VSC, you see a combination of the VSC defaults and my additions. In other words, my file exclusion setting inherits the global settings. Some workspace settings override the user settings while others inherit.

Exclusions for the Intelephense Extension

My main interest is in excluding files that the Intelephense PHP extension does not need to examine. This is important because my personal site has about 900 PHP files. In EW, that means 900 ghost files, all with the file extension .php. Intelephense will attempt to index them all, even though they contain no PHP, no HTML, or anything else that the environment needs to know about. Double the work for absolutely no benefit. In fact, I'm exploring the possibility that somehow the VTI files confuse Intelephense, although they shouldn't.

As I start editing more and more of my projects with VSC, I will simply get started by copying my settings.json file into the project.

It is also the case that Intelephense has its own exclusions setting:

Intelephense Exclusions

This setting inherits from the Files: Exclude setting, which means it will use the custom exclusions I've added. However, the recommendation from the developer of Intelephense is to enter your exclusions here. Doing so will result in the expansion of the workspace settings file. In my case, doing so results in this:

{
  "files.exclude": {
    "**/_vti_cnf/**": true,
    "**/_vti_pvt/**": true
  },
  "intelephense.files.exclude": [
    "**/.git/**",
    "**/.svn/**",
    "**/.hg/**",
    "**/CVS/**",
    "**/.DS_Store/**",
    "**/node_modules/**",
    "**/bower_components/**",
    "**/vendor/**/{Tests,tests}/**",
    "**/.history/**",
    "**/vendor/**/vendor/**",
    "**/_vti_cnf/**",
    "**/_vti_pvt/**"
  ]
}

Exclusions for the SFTP Extension

I'm a bit fuzzy about whether the important SFTP extension inherits exclusion settings from the VSC environment. My current belief is no. However, SFTP requires a JSON file in the .vscode folder for every project and its structure includes a similar feature:

{
    "name": "XXXXXXXX",
    "host": "fastiesites.xxxxxxxxxxx.com",
    "scheme": "sftp",
    "username": "fastiesites",
    "password": "xxxxxxxxxxxxxxx",
    "remotePath": "/usr/home/fastiesites/.../fastie.com/",
    "ignore": [
        "**/_vti_cnf/**",
        "**/_vti_pvt/",
        ".vscode",
        ".idea"
    ],
    "uploadOnSave": false
}

SFTP uses the "ignore" setting to accomplish the same thing. I still need to experiment to find out if it does inherit the workspace settings but in the meantime I create the sftp.json file from a template that includes these basic exclusions. I have confirmed that these exclusions work by using them in a project where the VTI files have not been excluded and observing that the metadata files are not published.

Metadata exclusions are important for SFTP because it halves the number of files that SFTP must handle. Although file size affects publishing performance more, each file carries protocol overhead and eliminating that is a plus.

Configuring the SFTP extension can be confusing, something I will address in a future tip.

A Dash of History

You may wonder why Vermeer decided to use what by any measure is a cumbersome structure for storing metadata. The reason is simple - almost a quarter of a century. It was cumbersome then, too, but also practical.

It's been so long that I can't remember what my PC of the time had in the way of RAM. Was it the 16GB that I have on my current system? Certainly not. How about a database into which the metadata could be stored? Yes, there were options, one of which was Microsoft's own JET engine. But for the time, using the file system to store data may have been the most efficient. If you wanted information about a particular file you need only look for its ghost in a sub-folder. Although this "chunk" style of data management sounds like a kludge, storage hardware was getting faster and faster all the time.

Vermeer was hardly the only programming team that used this approach. I did, years before FrontPage came out. So did many others. It worked. Now it's in the way.

By the way, here's a point of comparison. I've only let VSC touch about eight projects to date. So far, it's got over 400MB of metadata for itself and those projects. On my current PC that's hardly visible. In 1997, it would have been huge.

(This is the first in what I hope will be a continuing series of tips about how to use Visual Studio Code for those migrating from Expression Web.)

 

Tags: Expression Web, Programming, Tip, Visual Studio Code

A total of 21 related articles were found. See them all...