Code, Command Line
vim {file} — Vi IMproved, a programmers text editor
Commands
i – insert mode
esc – get out of insert mode
:{number} – go to that line number
:q – quit
:q! – force quit (no save)
:e! – discard edits to last saved state
:w – save document (write)
:wq – save and quit document
:ZZ – save and quit document
Moving Around
h, j, k, l — move cursor like arrow keys
$ – move cursor to end of current line
0 – move cursor to start of current line
w – move to next word
b – go back a word
ctrl f – page down
ctrl b – page up
Copy and Paste
y – yank or copy
yw – copy word
yy – copy whole line
#y – copy # of words. Example 5y (copy 5 words)
#yy – copy # of lines. Example 5yy (copy 5 lines)
p – paste
Undo and Delete
u – undo
x – delete current letter
dd – delete whole line
dw – delete next word
db – delete previous word
cw – delete next word and go into insert mode
cc – delete line and go into insert mode
Visual Mode
v – activate visual mode
Additional Shortcuts
shift i – go to start of curent line start insert mode
shift a – go to end of current line start insert mode
d arrowletter – delete word direction you point
Code
Form validation is an important part of web development. The user experience of your online forms will leave an impression on your visitors so it is important that you build great forms on your website. We will apply AngularJS to an existing online form.
Initial Form
Use the following HTML which uses Bootstrap CSS for formatting as a starting point. After you work through this example you can apply the changes to an existing form.
<div class="form-container">
<form name="myform" action="" method="post">
<div class="form-group">
<label for="firstname">First Name *</label>
<input type="text" name="firstname" placeholder="First Name">
</div><!-- .form-group -->
<div class="form-group">
<label for="lastname">Last Name *</label>
<input type="text" name="lastname" placeholder="Last Name">
</div><!-- .form-group -->
<div class="form-group">
<label for="email">Email Address *</label>
<input type="text" name="email" placeholder="Email Address">
</div><!-- .form-group -->
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div><!-- #form-container -->
Add AngularJS to your page.
Add AngularJS to the bottom of your page. I also added in the Bootstrap CDN for CSS styling. The ng-app
directive tells AngularJS that this is the root element of the AngularJS application. We will apply this to the div outside our form. The “form-container” class is optional we are using it for our demo. You will want to apply ng-app to a div outside your existing form.
<div class="form-container" ng-app>
<form ...>
...
</form>
</div><!-- #form-container -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
Add form validation.
Apply the following angular directives for form validation.
The ng-required directive indicates that a field is required. If a required field has no value the form will automatically have an ng-invalid class applied until the requirements are met.
<div class="form-group">
<label for="firstname">First Name *</label>
<input type="text" name="firstname" placeholder="First Name"
ng-required="true">
</div><!-- .form-group -->
Test form values
The ng-model directive binds an input, select, textarea (or custom form control) value to angular. Use the same field name and append user.fieldname to the front to bind it to the {{user}} data object which we will use to view our form values.
<div class="form-group">
<label for="firstname">First Name *</label>
<input type="text" name="firstname" placeholder="First Name"
ng-model="user.firstname"
ng-required="true">
</div><!-- .form-group -->
For testing we add an alert div to output our {{user}} data which will display our ng-model form values. Angular uses the double curly brackets to display data. Add this above the submit button.
<p class="alert alert-warning">Output: {{user}}</p>
Validate the email address
The ng-pattern directive is used on the email field for regular expression matching to validate the email address.
<div class="form-group">
<label for="email">Email Address *</label>
<input type="text" name="email" placeholder="Email Address"
ng-model="user.email"
ng-required="true"
ng-pattern="/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/">
</div><!-- .form-group -->
Disable the submit button until the form passes validation
The ng-disabled directive is applied to our submit button and will remain disabled until all the form validation passes.
<button type="submit" class="btn btn-default" ng-disabled="myform.$invalid">Submit</button>
Final touches
We are adding additional user prompts to let the user know there is missing field data.
- The ng-show directive will display this element until the requirements indicated in the property are met.
- The field was marked as required in the previous step by ng-required=”true” property. The myform.firstname.$invalid condition will return true until there is a value added into the field.
- We also added a $touched condition which means the field has been activated. This will not return true until the cursor has entered the field.
<div class="form-group">
<label for="firstname">First Name *</label>
<input type="text" name="firstname" placeholder="First Name"
ng-model="user.firstname"
ng-required="true">
<div ng-show="myform.firstname.$invalid && myform.firstname.$touched"
class="alert alert-warning">You must fill out your first name.</div>
</div><!-- .form-group -->
Completed Form
Here is the code for the completed form.
<div class="form-container" ng-app>
<form name="myform" action="" method="post">
<div class="form-group">
<label for="firstname">First Name *</label>
<input type="text" name="firstname" placeholder="First Name"
ng-model="user.firstname"
ng-required="true">
<div ng-show="myform.firstname.$invalid && myform.firstname.$touched"
class="alert alert-warning">You must fill out your first name.</div>
</div><!-- .form-group -->
<div class="form-group">
<label for="lastname">Last Name *</label>
<input type="text" name="lastname" placeholder="Last Name"
ng-model="user.lastname"
ng-required="true">
<div ng-show="myform.lastname.$invalid && myform.lastname.$touched"
class="alert alert-warning">You must fill out your last name.</div>
</div><!-- .form-group -->
<div class="form-group">
<label for="email">Email Address *</label>
<input type="text" name="email" placeholder="Email Address"
ng-model="user.email"
ng-required="true"
ng-pattern="/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/">
<div ng-show="myform.email.$invalid && myform.email.$touched"
class="alert alert-warning">This must be a valid email.</div>
</div><!-- .form-group -->
<!-- Display Form Values for Testing !!!Delete after testing!!! -->
<p class="alert alert-warning">Output: {{user}}</p>
<button type="submit" class="btn btn-default" ng-disabled="myform.$invalid">Submit</button>
</form>
</div><!-- #form-container -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
Code, Drupal, Tips
Prevent Browser caching
Put this at the top of your theme template.php file:
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
Download and enable the SecKit module:
https://www.drupal.org/project/seckit
There are some nice default settings. We can review tweak these settings as part of a security review when we have more time.
Code, Drupal
Use the following code to reference a NID from within a block.
if (arg(0) == 'node' && is_numeric(arg(1))) {
$nid = arg(1);
}
Code, Tips
Creating an HTML email signature can be a deceivingly difficult process. After having to tackle this issue a number of times this is the best method I have found to get the correct formatting.
- Start with a clean HTML file. You only want the divs for your signature.
- Save to your desktop and view it in your browser.
- Use in-line styles and link to external images for any logos or graphics.
- When the format is correct you want to use a browser on Windows and Outlook.
- Select the formatted details in your browser then copy and paste it into Outlook. As you know Microsoft does preserve a lot of hidden formatting when you cut and paste into their products. You may have experience headaches with Word doing a lot of crazy formatting. But in this case it is helping us preserve the formatting for your signature.
- Send a test email out with your updated signature and view it in various email clients to confirm the formatting is correct.
Code, Resources, Tips
MAMP Pro is great. It does a number things well which helps streamline the development process. The primary reasons I use MAMP Pro is that I can pull my sites from git into my local MAMP server, import the database quickly (including large SQL files), and it renders right in my browser right away at http://dev-projectname:8888 with very little setup. I will show you how to edit some configuration settings to get you setup and working quickly.
Setup your Dev environment:
- Using your Finder go to /Applications/MAMP/htdocs/ and create your Document Root folder for your project. Import your project files into this folder. Note: this htdocs folder is located at c:\MAMP\htdocs\ on the Windows version.
- Using MAMP Pro click the Hosts tab in MAMP Pro and click the + button on the bottom left.
- Add your development project details. I generally go with dev-projectname as the Server Name. This is what you will load in your browser to see your website some servers set this to localhost but I find dev-projectname is more useful for my purposes. The only other option you edit under Hosts is the Document Root which you set to the folder you created in Step 1.
- Click the Start icon in the top right and this gets your server running.
- Your website will now load in http://dev-projectname:8888.
The reason you want to use MAMP Pro is so you can develop your sites using http://dev-projectname:8888 rather than http://localhost/projectname:8888 which is a subdirectory and you run into issues with absolute URL paths. Just upgrade and use the Hosts feature. It’s so worth it.
Create/Import your Database:
- Click the MySQL tab and click phpMyAdmin to open that in your browser.
- Click the New link on the top left above the database list.
- Name your database dev_projectname. You can name the database whatever you like but to keep it organized I name it the same as the Server Name I created in the first set of instructions. Note that I use an underscore for the database name and a hyphen for the project URL.
- Now you can import your database.
- Edit your website configuration files to connect to this local database.
Importing large .sql files using phpMyAdmin:
If you are seeing this error “You probably tried to upload too large file. Please refer to documentation for ways to workaround this limit.” You need to edit your configuration files inside MAMP to import a database larger than 32MB.
- Go to the PHP tab in MAMP Pro. Make note of the PHP version you are using. I set my version to 5.6.x to match the version running on my Production Web Server.
- Go to File > Edit Template > PHP > select the version of PHP your server is running. Edit the following settings and save:
- post_max_size = 256M
- upload_max_filesize = 256M
- max_execution_time = 600
- max_input_time = 600
- memory_limit = 512M
- Restart your server and you should now be able to upload up to 256MB to your database.
Now that everything is running you should be able to quickly pull your sites from Github into your MAMP server; export your large database from Production and import it right into your local Dev; and have it all render at http://dev-projectname:8888 quickly. Make your edits and push your changes right onto QA and Production like a champ.