Blog creation workflow with new domain stuff.

master
Manager Bot 3 years ago
parent 36ecd56697
commit d6f5a09af6
  1. 15
      Web/lib/MJB/Web.pm
  2. 93
      Web/lib/MJB/Web/Controller/Blog.pm
  3. 60
      Web/lib/MJB/Web/Task/InitializeBlog.pm
  4. 10
      Web/templates/_base/error_window.html.ep
  5. 39
      Web/templates/_base/status_window.html.ep
  6. 9
      Web/templates/blog/create.html.ep
  7. 46
      Web/templates/blog/domain_hosted.html.ep
  8. 38
      Web/templates/blog/domain_owned.html.ep
  9. 2
      Web/templates/dashboard/index.html.ep

@ -181,10 +181,21 @@ sub startup ($self) {
$blog->post( '/page/remove' )->to('Dashboard#do_blog_page_remove' )->name('do_dashboard_blog_page_remove' );
# Blog Creation
$auth->get ( '/blog' )->to('Blog#create' )->name('show_blog_create' );
$auth->post( '/blog' )->to('Blog#do_create' )->name('do_blog_create' );
$auth->get ( '/blog' )->to('Blog#index' )->name('show_blog' );
$auth->get ( '/blog/domain/hosted' )->to('Blog#domain_hosted' )->name('show_blog_domain_hosted' );
$auth->post( '/blog/domain/hosted' )->to('Blog#do_domain_hosted' )->name('do_blog_domain_hosted' );
$auth->get ( '/blog/domain/owned' )->to('Blog#domain_owned' )->name('show_blog_domain_owned' );
$auth->post( '/blog/domain/owned' )->to('Blog#do_domain_owned' )->name('do_blog_domain_owned' );
$auth->get ( '/blog/initialize' )->to('Blog#do_initialize' )->name('do_blog_initialize' );
$auth->get ( '/blog/:id/settings' )->to('Blog#settings' )->name('show_blog_settings' );
$auth->post( '/blog/:id/settings' )->to('Blog#do_settings' )->name('do_blog_settings' );
#
#
#
#$auth->get ( '/blog' )->to('Blog#create' )->name('show_blog_create' );
#$auth->post( '/blog' )->to('Blog#do_create' )->name('do_blog_create' );
#$auth->get ( '/blog/:id/settings' )->to('Blog#settings' )->name('show_blog_settings' );
#$auth->post( '/blog/:id/settings' )->to('Blog#do_settings' )->name('do_blog_settings' );
# Admin Dashboard
$admin->get ( '/admin' )->to('Admin#index' )->name('show_admin' );

@ -2,43 +2,86 @@ package MJB::Web::Controller::Blog;
use Mojo::Base 'Mojolicious::Controller', -signatures;
use Try::Tiny;
sub create ($c) {
# Blog Create Work Flow:
# 1. Choose Domain
# 2. Choose Blog Settings
# 3. Information Page For Initial Instructions
sub index ( $c ) {
$c->redirect_to( 'show_blog_domain_hosted' );
}
sub do_create ($c) {
$c->stash->{template} = 'blog/create';
# Initial blog creation entry point when the user
# wants to use one of the domains that we provide.
sub domain_hosted ( $c ) {
push @{$c->stash->{errors}}, $c->flash('error_message')
if $c->flash('error_message');
my $domain_type = $c->stash->{form_domain_type} = $c->param('domain_type');
my $domain = $c->stash->{form_owned_domain} = $c->param('owned_domain');
my $subdomain = $c->stash->{form_hosted_subdomain} = $c->param('hosted_subdomain');
}
sub do_domain_hosted ( $c ) {
my $sub_domain = $c->param('subdomain');
my $top_domain = $c->db->hosted_domain( $c->param('hosted_domain_id') );
push @{$c->stash->{errors}}, "Please select a domain from the drop down menu."
unless $top_domain;
push @{$c->stash->{errors}}, "Please enter a value for the subdomain."
unless $sub_domain;
push @{$c->stash->{errors}}, "Unknown domain type submitted."
unless $domain_type eq 'owned' or $domain_type eq 'hosted';
push @{$c->stash->{errors}}, "That domain name is already being used."
unless $c->db->domains( { name => $sub_domain . '.' . $top_domain->name } )->count == 0;
if ( $domain_type eq 'hosted' ) {
push @{$c->stash->{errors}}, "You must enter a subdomain."
unless $subdomain;
if ( $c->stash->{errors} ) {
$c->flash( errors => $c->stash->{errors} );
$c->redirect_to( $c->url_for( 'show_blog_domain_hosted' ) );
return;
}
$subdomain = lc($subdomain);
$c->redirect_to( $c->url_for( 'do_blog_initialize' )->query(
domain => $sub_domain . '.' . $top_domain->name,
));
}
push @{$c->stash->{errors}}, "Your subdomain may only contain letters, numbers and hypens."
unless $subdomain =~ /^[a-z0-9-]+$/;
# Initial blog creation entry point when the user
# wants to use a domain that they own.
sub domain_owned ( $c ) {
$c->stash->{dns_record} = 'external.' . $c->db->hosted_domains->first->name;
} elsif ( $domain_type eq 'owned' ) {
push @{$c->stash->{errors}}, "You must enter a domain."
unless $domain;
}
sub do_domain_owned ( $c ) {
my $domain_name = $c->param('domain_name');
push @{$c->stash->{errors}}, "Please enter a value for the domain name."
unless $domain_name;
return if $c->stash->{errors};
push @{$c->stash->{errors}}, "That domain name is already being used."
unless $c->db->domains( { name => $domain_name } )->count == 0;
$domain = $domain ? $domain : $subdomain . '.' . $c->config->{customer_domain};
if ( $c->stash->{errors} ) {
$c->flash( errors => $c->stash->{errors} );
$c->redirect_to( $c->url_for( 'show_blog_domain_owned' ) );
return;
}
$c->redirect_to( $c->url_for( 'do_blog_initialize' )->query(
domain => $domain_name
));
}
# This is a special exception, it's actually a get request, because we want it
# forwarded from the domain_hosted / domain_owned requests, and redirecting to
# a post doesn't work. However, since we're doing things rather than displaying
# things, it'll be named with the do_
sub do_initialize ( $c ) {
my $domain = $c->param('domain');
# Do we already have this domain name?
if ( $c->db->domain( { name => $domain } ) ) {
push @{$c->stash->{errors}}, "That domain name has been taken.";
$c->flash( errors => [ 'That domain name is already being hosted.' ] );
$c->redirect_to( $c->url_for( 'show_blog_domain_hosted' ) );
return;
}
@ -66,11 +109,14 @@ sub do_create ($c) {
return $blog;
});
} catch {
push @{$c->stash->{errors}}, "Account could not be created: $_";
push @{$c->stash->{errors}}, "Blog could not be created: $_";
};
# Choose a web server to deploy to
return if $c->stash->{errors};
if ( $c->stash->{errors} ) {
$c->flash( errors => $c->stash->{errors} );
$c->redirect_to( $c->url_for( 'show_blog_domain_hosted' ) );
return;
}
# Schedule a job to deploy the website
my $ssl_job_id = $c->minion->enqueue( 'create_ssl_cert', [ $blog->id ], {
@ -81,7 +127,6 @@ sub do_create ($c) {
$blog->create_related( 'builds', { job_id => $ssl_job_id } );
$c->redirect_to( $c->url_for( 'show_blog_settings', { id => $blog->id } ) );
}
sub settings ( $c ) {

@ -0,0 +1,60 @@
package MJB::Web::Task::InitializeBlog;
use Mojo::Base 'MJB::Web::Task', -signatures;
use Mojo::File qw( curfile );
use File::Copy::Recursive qw( dircopy );
use IPC::Run3;
# This needs to do all of the things:
# 1 - Make nginx config
# 2 - Whatever the ansible deploy-site thing does.
#
sub run ( $job, $blog_id ) {
$job->note( _mds_template => 'build_static' );
my $build_dir = $job->checkout_repo( $blog_id );
my $blog = $job->app->db->blog( $blog_id );
$job->note( is_clone_complete => 1 );
# Show the user the commit we're on.
$job->system_command( [ 'git', '-C', $build_dir->child('src')->to_string, 'log', '-1' ] );
$build_dir->child('build')->make_path;
$job->system_command( [qw( podman run -ti --rm -v .:/srv/jekyll -e JEKYLL_ROOTLESS=1 docker.io/jekyll/jekyll jekyll build ) ], {
chdir => $build_dir->child('src')->to_string,
});
$job->process_webroot(
$blog,
$build_dir->child('src')->child('_site')->to_string,
$build_dir->child('build')->to_string
);
#==
# Build Site Config
#== TODO: There is two different files made here, one is done by ansible -- pick one,
# probably this one.
Mojo::File->new($build_dir)->child('build')->child('site.yml')->spurt(
YAML::Dump({
domain => $blog->domain->name,
www_dir => "$build_dir/build/",
})
);
$job->note( is_build_complete => 1 );
# Go to the build directory and make $build_dir/.
$ENV{MARKDOWNSITE_CONFIG} = Mojo::File->new($build_dir->to_string)->child('build')->child('site.yml');
$job->system_command( [ 'ansible-playbook', '/etc/ansible/deploy-website.yml' ] );
$job->note( is_deploy_complete => 1 );
$job->finish( );
}
1;

@ -1,10 +0,0 @@
% if ( $c->stash->{errors} ) {
<div style="margin-top: 2em" class="alert alert-danger" role="alert">
There were errors with your request that could not be resolved:
<ul>
% for my $error ( @{$c->stash->{errors}} ) {
<li><%= $error %></li>
% }
</ul>
</div>
% }

@ -0,0 +1,39 @@
% if ( my $confirmation = flash 'confirmation' ) {
<div style="margin-top: 2em" class="alert alert-success" role="alert">
<%== $confirmation %>
</div>
% }
% if ( my $error_message = flash 'error_message' ) {
<div style="margin-top: 2em" class="alert alert-danger" role="alert">
<%== $error_message %>
</div>
% }
% if ( $c->stash->{success} ) {
<div style="margin-top: 2em" class="alert alert-success" role="alert">
<%= $c->stash->{success_message} %>
</div>
% }
% if ( my $errors = flash 'errors' ) {
<div style="margin-top: 2em" class="alert alert-danger" role="alert">
There were errors with your request that could not be resolved:
<ul>
% for my $error ( @{$errors} ) {
<li><%= $error %></li>
% }
</ul>
</div>
% }
% if ( $c->stash->{errors} ) {
<div style="margin-top: 2em" class="alert alert-danger" role="alert">
There were errors with your request that could not be resolved:
<ul>
% for my $error ( @{$c->stash->{errors}} ) {
<li><%= $error %></li>
% }
</ul>
</div>
% }

@ -45,8 +45,15 @@
<label class="form-check-label" for="inlineRadio1">Use our domain</label>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="domain-addon-1">https://</span>
<input type="text" name="hosted_subdomain" class="form-control" placeholder="YourSiteName" aria-label="domain name" aria-describedby="domain-addon">
<span class="input-group-text" id="domain-addon">.<%= $c->config->{customer_domain} %></span>
<span class="input-group-text" id="domain-addon-2">.
<select class="form-select" aria-label="Select Domain Name">
% foreach my $hosted_domain ( $c->db->hosted_domains->all ) {
<option name="hosted_domain_id" value="<%= $hosted_domain->id %>"><%= $hosted_domain->name %></option>
% }
</select>
</span>
</div>
</div>
<div class="col" style="border-left: 1px solid #ccc">

@ -0,0 +1,46 @@
% layout 'standard', title => 'Create Blog', sb_active => 'dashboard';
<div class="mt-5">
<div class="progress" style="height: 1px;">
<div class="progress-bar" role="progressbar" style="width: 33%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-light" role="progressbar" style="width: 34%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-light" role="progressbar" style="width: 33%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress mt-1" style="height: 20px;">
<div class="progress-bar bg-success" role="progressbar" style="width: 33%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">Domain Name</div>
<div class="progress-bar" role="progressbar" style="width: 34%;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">Blog Settings</div>
<div class="text-center progress-bar-striped" style="width: 33%">Finish</div>
</div>
</div>
<h3 class="h3 mt-4 mb-4">Create new blog</h3>
<p>The first step of creating your new blog is to choose a domain name.</p>
<p>You can host your blog on a sub domain we provide for free, without any additional configuration. Enter the sub domain you'd like below and press continue.</p>
<p>If you own your own domain name and would like to use that, please <a href="<%= $c->url_for( 'show_blog_domain_owned' ) %>">click here</a> to continue.</p>
%= include '_base/status_window';
<form class="mt-5" method="POST" action="<%= $c->url_for( 'do_blog_domain_hosted' ) %>">
<div class="row">
<input type="hidden" name="repo_id" value="<%= stash 'form_repo_id' %>">
<div class="col-2">
</div>
<div class="col-8">
<div class="input-group mb-3">
<span class="input-group-text" id="domain-addon-1">https://</span>
<input type="text" name="subdomain" class="form-control" placeholder="YourSiteName" aria-label="domain name" aria-describedby="domain-addon">
<span class="input-group-text" id="domain-addon-2">.
<select name="hosted_domain_id" class="form-select" aria-label="Select Domain Name">
% foreach my $hosted_domain ( $c->db->hosted_domains->all ) {
<option name="hosted_domain_id" value="<%= $hosted_domain->id %>"><%= $hosted_domain->name %></option>
% }
</select>
</span>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary float-end mt-3">Continue &rarr;</button>
</form>

@ -0,0 +1,38 @@
% layout 'standard', title => 'Create Blog', sb_active => 'dashboard';
<div class="mt-5">
<div class="progress" style="height: 1px;">
<div class="progress-bar" role="progressbar" style="width: 33%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-light" role="progressbar" style="width: 34%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-light" role="progressbar" style="width: 33%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress mt-1" style="height: 20px;">
<div class="progress-bar bg-success" role="progressbar" style="width: 33%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">Domain Name</div>
<div class="progress-bar" role="progressbar" style="width: 34%;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">Blog Settings</div>
<div class="text-center progress-bar-striped" style="width: 33%">Finish</div>
</div>
</div>
<h3 class="h3 mt-4 mb-4">Create new blog</h3>
<p>The first step of creating your new blog is to choose a domain name.</p>
<p>To use your own domain name, you'll need to set the a <span class="fw-bold">CNAME</span> record on your domain to point to <span class="fw-bold"><%= $dns_record %></span>. Until this record exists, your blog will not be accessable from the Internet.</p>
<p>If you would like to use a domain name we provide, please <a href="<%= $c->url_for( 'show_blog_domain_hosted' ) %>">click here</a> to go back.</p>
%= include '_base/status_window';
<form class="mt-5" method="POST" action="<%= $c->url_for( 'do_blog_domain_owned' ) %>">
<div class="row">
<div class="col-2">
</div>
<div class="col-8">
<div class="input-group mb-3">
<span class="input-group-text" id="domain-addon-1">https://</span>
<input type="text" name="domain_name" class="form-control" placeholder="your.domain.com" aria-label="domain name" aria-describedby="domain-addon">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary float-end mt-3">Continue &rarr;</button>
</form>

@ -9,7 +9,7 @@
<div class="row">
<div class="col">
<div class="float-end">
<a style="text-decoration: none;" href="<%= $c->url_for( 'show_blog_create' ) %>">
<a style="text-decoration: none;" href="<%= $c->url_for( 'show_blog_domain_hosted' ) %>">
<span style="color: green; width: 32px; height: 32px;" data-feather="plus-circle"></span>
<cpan style="color: black; vertical-align: 30%; font-size: 16px">New Blog</span>
</a>

Loading…
Cancel
Save