src/PuphpetBundle/Resources/views/apache/vhost.html.twig
{% set uniqid = uniqid ?? uniqid('vhost_') %}
{% set idBase = "apache-vhosts-#{uniqid}" %}
{% set nameBase = "apache[vhosts][#{uniqid}]" %}
{% set serveraliases = (vhost.serveraliases is defined) ? vhost.serveraliases : [] %}
{% set ssl = (vhost.ssl is defined and vhost.ssl) ? true : false %}
{% set ssl_cert = (vhost.ssl_cert is defined) ? vhost.ssl_cert : '' %}
{% set ssl_key = (vhost.ssl_key is defined) ? vhost.ssl_key : '' %}
{% set ssl_chain = (vhost.ssl_chain is defined) ? vhost.ssl_chain : '' %}
{% set ssl_certs_dir = (vhost.ssl_certs_dir is defined) ? vhost.ssl_certs_dir : '' %}
{% set ssl_protocol = (vhost.ssl_protocol is defined) ? vhost.ssl_protocol : '' %}
{% set ssl_cipher = (vhost.ssl_cipher is defined) ? vhost.ssl_cipher : '' %}
{% set ssl_letsencrypt_enabled = (ssl and ssl_cert == 'LETSENCRYPT') ? true : false %}
{% set ssl_custom_enabled = (ssl and ssl_cert != 'LETSENCRYPT') ? true : false %}
{% set setenvifs = (vhost.setenvif is defined) ? vhost.setenvif : [] %}
{% set directories = (vhost.directories is defined) ? vhost.directories : [] %}
{% set files_matches = (vhost.files_match is defined) ? vhost.files_match : [] %}
<div id="{{ idBase }}" data-uniqid="{{ uniqid }}" data-name="{{ nameBase }}"
class="tab-pane {{ active is defined and active ? 'active' }}">
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-servername">
Server Name
</label>
<input type="text" id="{{ idBase }}-servername"
name="{{ nameBase }}[servername]"
placeholder="awesome.test" class="form-control"
value="{{ vhost.servername }}" />
<div class="help-block">
Don't forget to update your computer's hosts file!
</div>
</div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-serveraliases">
Server Aliases
</label>
<select id="{{ idBase }}-serveraliases"
name="{{ nameBase }}[serveraliases][]"
multiple class="form-control select-tags-editable">
{% for alias in serveraliases %}
<option selected value="{{ alias }}">{{ alias }}</option>
{% endfor %}
</select>
<div class="help-block">
Separated by comma.
</div>
</div>
<div class="clearfix"></div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-docroot">
Document Root
</label>
<input type="text" id="{{ idBase }}-docroot"
name="{{ nameBase }}[docroot]"
placeholder="/var/www" class="form-control"
value="{{ vhost.docroot }}" />
<div class="help-block">
Location of your site's index.php file, or other landing page.
</div>
</div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-port">
Port
</label>
<input type="number" id="{{ idBase }}-port"
name="{{ nameBase }}[port]"
placeholder="80" class="form-control"
value="{{ vhost.port }}" />
<div class="help-block">
<code>80</code> for normal browsing, if you choose another append
it to the URL in your browser, eg: <code>http://awesome.test:1337</code>
</div>
</div>
<div class="clearfix"></div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-setenvif">
SetEnvIf
</label>
<select id="{{ idBase }}-setenvif"
name="{{ nameBase }}[setenvif][]"
multiple class="form-control select-tags-editable">
{% for setenvif in setenvifs %}
<option selected value="{{ setenvif }}">{{ setenvif }}</option>
{% endfor %}
</select>
<div class="help-block">
<code>name value</code>, separated by comma.
</div>
</div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-custom_fragment">
Additional Settings
</label>
<select id="{{ idBase }}-custom_fragment"
name="{{ nameBase }}[custom_fragment][]"
multiple class="form-control select-tags-editable">
{% for rule in custom_fragment %}
<option selected value="{{ rule }}">{{ rule }}</option>
{% endfor %}
</select>
<div class="help-block">
Additional rules, separated by comma.
</div>
</div>
<div class="clearfix"></div>
<input type="hidden" name="{{ nameBase }}[ssl]" value="0" />
<div class="panel panel-info">
<div class="panel-heading">SSL Options</div>
<div class="panel-body">
<ul class="nav nav-tabs nested-tabs sortable">
<li class="{% if ssl_letsencrypt_enabled or not ssl %}active{% endif %}">
<a href="#" data-target="#{{ idBase }}-ssl-letsencrypt-container"
data-toggle="tab">Let's Encrypt SSL</a>
</li>
<li class="{% if ssl_custom_enabled %}active{% endif %}">
<a href="#" data-target="#{{ idBase }}-ssl-custom-container"
data-toggle="tab">Custom SSL</a>
</li>
</ul>
<div class="tab-content">
<div id="{{ idBase }}-ssl-letsencrypt-container"
class="tab-pane {% if ssl_letsencrypt_enabled or not ssl %}active{% endif %}">
<div class="checkbox checkbox-md no-padding mb-20">
<input type="checkbox" id="{{ idBase }}-ssl-letsencrypt-enabled"
name="{{ nameBase }}[ssl]" value="1"
{% if ssl_letsencrypt_enabled %}checked{% endif %}
data-toggle="checkbox-collapse"
data-target="#{{ idBase }}-ssl-letsencrypt-enabled-container"
data-enforce-group-single="{{ idBase }}-ssl"
data-enable-on-check data-disable-on-uncheck />
<label for="{{ idBase }}-ssl-letsencrypt-enabled">Use Let's Encrypt SSL</label>
</div>
<div class="clearfix"></div>
<div id="{{ idBase }}-ssl-letsencrypt-enabled-container"
class="collapse {% if ssl_letsencrypt_enabled %}in{% endif %}">
<div class="help-block">
<p>Let’s Encrypt is a new Certificate Authority:
It’s free, automated, and open.</p>
<p>Generates a valid SSL certificate. Automatically
renews the certificate once a month. It's awesome!</p>
<p><a href="https://letsencrypt.org/" target="_blank">More information</a></p>
<p><strong>This will only work on a public domain!</strong></p>
<p>Do not choose this option for local development domains.</p>
<p>THE DOMAIN MUST BE PUBLIC AND REACHABLE FROM THE INTERNET.</p>
<p>If you do not know your server's IP address ahead of time,
<code>$ vagrant up</code> may fail initially. You need to assign
your domain to the new server via an <code>A</code> record
or a floating IP address. As long as your domain resolves
to the created server this will work!</p>
<p>Simply run <code>$ vagrant provision</code> once the domain is
resolving properly!</p>
<p>Make sure to also add this domain to the
<a href="#letsencrypt" data-toggle="tab">Let's Encrypt tab by clicking here</a>!</p>
<p>To redirect all non-SSL traffic to SSL, create two vhosts - one on
port 80 and one on port 443.</p>
<p>Add <code>Redirect permanent / https://{YOUR_VHOST_NAME}/</code> to
the non-SSL vhost's Custom Directives to redirect all traffic to
the SSL vhost.</p>
</div>
</div>
<input type="hidden" name="{{ nameBase }}[ssl_cert]"
value="LETSENCRYPT" />
<input type="hidden" name="{{ nameBase }}[ssl_key]"
value="LETSENCRYPT" />
<input type="hidden" name="{{ nameBase }}[ssl_chain]"
value="LETSENCRYPT" />
<input type="hidden" name="{{ nameBase }}[ssl_certs_dir]"
value="LETSENCRYPT" />
<input type="hidden" name="{{ nameBase }}[ssl_protocol]"
value="{{ ssl_protocol }}" />
<input type="hidden" name="{{ nameBase }}[ssl_cipher]"
value="{{ ssl_cipher }}" />
</div>
<div id="{{ idBase }}-ssl-custom-container"
class="tab-pane {% if ssl_custom_enabled %}active{% endif %}">
<div class="checkbox checkbox-md no-padding mb-20">
<input type="checkbox" id="{{ idBase }}-ssl-custom-enabled"
name="{{ nameBase }}[ssl]" value="1"
{% if ssl_custom_enabled %}checked{% endif %}
data-toggle="checkbox-collapse"
data-target="#{{ idBase }}-ssl-custom-enabled-container"
data-enforce-group-single="{{ idBase }}-ssl"
data-enable-on-check data-disable-on-uncheck />
<label for="{{ idBase }}-ssl-custom-enabled">Use Custom SSL</label>
</div>
<div class="clearfix"></div>
<div id="{{ idBase }}-ssl-custom-enabled-container"
class="collapse {% if ssl_custom_enabled %}in{% endif %}">
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-ssl_cert">
SSL Certificate File Path
</label>
<input type="text" id="{{ idBase }}-ssl_cert"
name="{{ nameBase }}[ssl_cert]"
placeholder="/leave/blank/for/sample" class="form-control"
value="{{ ssl_cert }}" />
<div class="help-block">
<p>Absolute path to SSL Certificate File. Usually ends in .crt.
Leave blank to use a generic one.
<strong>DO NOT LEAVE BLANK FOR PRODUCTION</strong>.
<span class="label label-info" data-toggle="help-text">
<i class="fa fa-ellipsis-h"></i></span>
</p>
<div class="hidden">
<p>This should be the location within the VM, not the host!</p>
<p><a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslcertificatefile"
target="_blank">Learn more about this</a>.</p>
</div>
</div>
</div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-ssl_key">
SSL Certificate Key File
</label>
<input type="text" id="{{ idBase }}-ssl_key"
name="{{ nameBase }}[ssl_key]"
placeholder="/leave/blank/for/sample" class="form-control"
value="{{ ssl_key }}" />
<div class="help-block">
<p>Absolute path to SSL Certificate Key File. Usually ends in .key.
Leave blank to use a generic one.
<strong>DO NOT LEAVE BLANK FOR PRODUCTION</strong>.
<span class="label label-info" data-toggle="help-text">
<i class="fa fa-ellipsis-h"></i></span>
</p>
<div class="hidden">
<p>This should be the location within the VM, not the host!</p>
<p><a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslcertificatekeyfile"
target="_blank">Learn more about this</a>.</p>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-ssl_chain">
SSL Certificate Chain File Path
</label>
<input type="text" id="{{ idBase }}-ssl_chain"
name="{{ nameBase }}[ssl_chain]"
placeholder="/leave/blank/for/sample" class="form-control"
value="{{ ssl_chain }}" />
<div class="help-block">
<p>Absolute path to SSL Certificate Chain File.
Usually ends in .crt and may have the name of your SSL provider.
Leave blank to use a generic one.
<strong>DO NOT LEAVE BLANK FOR PRODUCTION</strong>.
<span class="label label-info" data-toggle="help-text">
<i class="fa fa-ellipsis-h"></i></span>
</p>
<div class="hidden">
<p>This should be the location within the VM, not the host!</p>
<p><a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslcertificatechainfile"
target="_blank">Learn more about this</a>.</p>
</div>
</div>
</div>
<div class="form-group col-xs-12 col-sm-6">
<label for="{{ idBase }}-ssl_certs_dir">
SSL CA Certificate Path
</label>
<input type="text" id="{{ idBase }}-ssl_certs_dir"
name="{{ nameBase }}[ssl_certs_dir]"
placeholder="/leave/blank/for/sample" class="form-control"
value="{{ ssl_certs_dir }}" />
<div class="help-block">
<p>Absolute path to SSL CA Certificate.
Leave blank to use a generic one.
<strong>DO NOT LEAVE BLANK FOR PRODUCTION</strong>.
<span class="label label-info" data-toggle="help-text">
<i class="fa fa-ellipsis-h"></i></span>
</p>
<div class="hidden">
<p>This should be the location within the VM, not the host!</p>
<p><a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslcacertificatepath"
target="_blank">Learn more about this</a>.</p>
</div>
</div>
</div>
<input type="hidden" name="{{ nameBase }}[ssl_protocol]"
value="{{ ssl_protocol }}" />
<input type="hidden" name="{{ nameBase }}[ssl_cipher]"
value="{{ ssl_cipher }}" />
<div class="clearfix"></div>
<div class="help-block col-xs-12">
<p>To redirect all non-SSL traffic to SSL, create two vhosts - one on
port 80 and one on port 443.</p>
<p>Add <code>Redirect permanent / https://{YOUR_VHOST_NAME}/</code> to
the non-SSL vhost's Custom Directives to redirect all traffic to
the SSL vhost.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="panel panel-info">
<div class="panel-heading">Virtual Host Directory/Location/Files Directives</div>
<div class="panel-body">
<ul class="nav nav-tabs nested-tabs sortable dropdown">
<li class="add">
<a href="#" data-toggle="dropdown" id="{{ idBase }}-dropDownMenu">
Add <span class="caret"></span></a>
<ul class="dropdown-menu" aria-labelledby="{{ idBase }}-dropDownMenu">
<li><a href="{{ path('puphpet.apache.directory', {
'vhostId': uniqid,
}) }}"
data-toggle="add-block">Empty Directory</a></li>
<li><a href="{{ path('puphpet.apache.files_match', {
'vhostId': uniqid,
}) }}"
data-toggle="add-block">Empty FilesMatch</a></li>
<li role="separator" class="divider"></li>
<li><a href="{{ path('puphpet.apache.pregenerated_directory', {
'vhostId': uniqid,
'pregenerated': 'html',
}) }}"
data-toggle="add-block">Basic HTML</a></li>
<li><a href="{{ path('puphpet.apache.pregenerated_directory', {
'vhostId': uniqid,
'pregenerated': 'php',
}) }}"
data-toggle="add-block">Basic PHP</a></li>
<li role="separator" class="divider"></li>
<li><a href="{{ path('puphpet.apache.pregenerated_directory', {
'vhostId': uniqid,
'pregenerated': 'symfony2_3',
}) }}"
data-toggle="add-block">Symfony 2 & 3</a></li>
<li><a href="{{ path('puphpet.apache.pregenerated_directory', {
'vhostId': uniqid,
'pregenerated': 'symfony4',
}) }}"
data-toggle="add-block">Symfony 4</a></li>
<li><a href="{{ path('puphpet.apache.pregenerated_directory', {
'vhostId': uniqid,
'pregenerated': 'laravel',
}) }}"
data-toggle="add-block">Laravel</a></li>
<li><a href="{{ path('puphpet.apache.pregenerated_directory', {
'vhostId': uniqid,
'pregenerated': 'wordpress',
}) }}"
data-toggle="add-block">Wordpress</a></li>
</ul>
</li>
{% for index, directory in directories %}
{% set blockId = "#{idBase}-directories-#{index}" %}
{% set blockName = "#{nameBase}[directories][#{index}]" %}
<li class="{{ loop.first ? 'active' }}">
<a href="#" data-target="#{{ blockId }}"
data-toggle="tab">{{ index }}</a>
<div class="btn-group">
<button type="button" class="btn btn-default"
data-toggle="delete-block"
data-target="#{{ blockId }}">
<i class="fa fa-close"></i></button>
</div>
<input type="hidden" name="{{ blockName }}" value="1" />
</li>
{% endfor %}
</ul>
<div class="tab-content">
<div class="empty-tabs">
<i class="fa fa-share fa-rotate-270" aria-hidden="true"></i>
Click to add a virtual host Directory/Location/Files or DirectoryMatch/LocationMatch/FilesMatch
</div>
{% for index, directory in directories %}
{% if directory.provider is not defined
or directory.provider|lower not in [
'directory', 'directorymatch', 'location', 'locationmatch', 'files', 'filesmatch'
] %}{% set provider = 'directory' %}{% else %}{% set provider = directory.provider %}{% endif %}
{% include "PuphpetBundle:apache:#{provider}.html.twig" with {
'vhostId': uniqid,
'directory': directory,
'uniqid': index,
'active': loop.first ? true : false,
} %}
{% endfor %}
</div>
</div>
</div>
<div class="clearfix"></div>
</div>