Replacing Tags and Custom Code Analysis in HTML
This is the second part of a previous post on Searching for Patterns in HTML using ReSharper 6. In the first part we covered the basics of searching for HTML tags, including the use of CSS selectors, using Structural Search and Replace. In this second and final post, we are going to put what we have learned to use, to not only allow us to replace our findings, but also as a means of extending ReSharper with custom patterns, which is the core idea behind Structural Search and Replace.
The same dialog box that is used to search for patterns, can also be employed to replace patterns. On the top-right of the window, there is a Replace button which activates a section to enter a replacement pattern
providing us with an option to specify the pattern we want to replace with, as well as the scope for it (Look In), be it Solution, Current Project or Current File.
Hitting Replace will now replace all entries based on scope definition.
Replacing with placeholders
The Replace Pattern also allows placeholders to be used. One useful benefit could be to search for certain incorrect usages of a tag and have it fixed up. For instance, let’s assume that we need to make sure all links have an icon associated with them.
What we would need to do is find all href that do not contain an img tag and add it. Our patterns would look like this:
In order to only select those links that do not have an image, we would need to define a CSS selector for $content$
Detecting code smells with patterns
We have seen so far how to search and replace HTML. We can now take it one step further and use patterns to detect code smells or just HTML code constructs that we’d like to modify for one reason or another. As mentioned at the start of the post, that is Structural Search and Replace’s core idea, to allow us to extend ReSharper with custom analysis (Search) and quick-fixes (Replace).
There are two ways to do this: use the Search with Pattern dialog as shown thus far, but instead of hitting the Find button, we hit Save or define the Custom Pattern via ReSharper | Options. The former ends up also as a custom pattern so we’ll just show how it is done using the latter approach.
1. Select ReSharper | Options | Custom Patterns and click Add Pattern .
2. Define the pattern as before. In our case, it would be
We can establish the level of severity (red rectangle) we wish to give the pattern. In our case, we select Warning. It is also important to define the Description of the search. This serves not only as the description (yellow rectangle) in the pattern entry, but also the message that will be displayed when the pattern is encountered. Finally we provide description for the replacement pattern (green rectangle). This replace is what is then considered a quick-fix.
As soon as we save this pattern, it will become active. ReSharper will now highlight anywhere in our code where this pattern matches.
Since it has a replacement, ReSharper now offers us to press Alt+Enter to fix the issue
It’s important to note that we can still do a global Search and Replace even when patterns have been saved. We do not lose that functionality. What we do gain is custom code analysis that works both as we glance through our code and as part of ReSharper’s Find Code Issues functionality to highlight any potential issues in our code.
Structural Search and Replace in ReSharper allows for more customization when it comes to defining patterns. For example, we can:
- Use regular expressions (and negative regular expressions) for attribute names, values and for content in between tags.
- Use CSS selectors for tag and content placeholders.
- Constraint control types for ASP.NET tag placeholders.
- Limit minimum and maximum number of attributes inside tags and elements in content placeholders.
We have just covered some of them in these two posts. Explore them, let us know what you like, what you don’t like and send us your feedback.
Subscribe to Blog updates
Thanks, we've got you!
Eager, Lazy and Explicit Loading with Entity Framework Core
Entity Framework Core (EF Core) supports a number of ways to load related data. There’s eager loading, lazy loading, and explicit loading. Each of these approaches have their own advantages and drawbacks. In this post, let’s have a quick look at each of these ways to load data for navigational prope…
OSS Power-Ups: bUnit – Webinar Recording
The recording of our webinar, OSS Power-Ups: bUnit, with Egil Hansen and Steven Giesel, is available. This was the twelfth episode of our OSS Power-Ups series, where we put a spotlight on open-source .NET projects. Subscribe to our community newsletter to receive notifications about future webi…
Accelerating Your Testing Workflow with Unit Test Creation and Navigation
Unit tests play an important role in our daily development workflow. They help us ensure our codebase's correctness when writing new functionality or performing refactorings to improve readability and maintainability. In the process, we often create new test files that accompany the p…
Introducing Predictive Debugging: A Game-Changing Look into the Future
With the introduction of debugging tools, software developers were empowered to interactively investigate the control flow of software programs to find bugs in live environments. At JetBrains, we've always strived to improve the art of debugging. Besides the more standard things you expect from a de…