diff --git a/Web/lib/MJB/Web.pm b/Web/lib/MJB/Web.pm index 73d64de..2276e29 100644 --- a/Web/lib/MJB/Web.pm +++ b/Web/lib/MJB/Web.pm @@ -185,6 +185,14 @@ sub startup ($self) { $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 + $auth->get ( '/admin' )->to('Admin#index' )->name('show_admin' ); + $auth->get ( '/admin/people' )->to('Admin#people' )->name('show_admin_people' ); + $auth->get ( '/admin/person/:id' )->to('Admin#person' )->name('show_admin_person' ); + $auth->get ( '/admin/blogs' )->to('Admin#blogs' )->name('show_admin_blogs' ); + $auth->get ( '/admin/settings' )->to('Admin#settings' )->name('show_admin_settings' ); + } 1; diff --git a/Web/lib/MJB/Web/Controller/Admin.pm b/Web/lib/MJB/Web/Controller/Admin.pm new file mode 100644 index 0000000..c64df23 --- /dev/null +++ b/Web/lib/MJB/Web/Controller/Admin.pm @@ -0,0 +1,409 @@ +package MJB::Web::Controller::Admin; +use Mojo::Base 'Mojolicious::Controller', -signatures; + +sub index ( $c ) { + +} + +sub people ( $c ) { + +} + +sub person ( $c ) { + +} + +sub blogs ( $c ) { + +} + +1; + +__END__ + + + + + + + + + +sub index ($c) { + push @{$c->stash->{blogs}}, + $c->stash->{person}->search_related('blogs')->all; +} + +sub blog ( $c ) { + my $blog = $c->stash->{blog}; +} + +sub blog_posts ( $c ) { + my $blog = $c->stash->{blog}; + + my $blog_posts = $c->stash->{blog_posts} = [ map { $_->read } @{$c->jekyll($blog->domain->name)->list_posts} ]; +} + +sub blog_post_edit ( $c ) { + my $blog = $c->stash->{blog}; + + my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); + + if ( ! $post ) { + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); + } +} + +sub blog_post_alter ( $c ) { + my $blog = $c->stash->{blog}; + + my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); + + if ( ! $post ) { + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); + } +} + +sub do_blog_post_remove ( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + my $post = $jekyll->get_post( $c->param('file') ); + + $jekyll->remove_markdown_file( $post ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "That post has been removed." ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); +} + + + +sub do_blog_post_edit ( $c ) { + my $blog = $c->stash->{blog}; + + my $title = $c->stash->{form_title} = $c->param('postTitle'); + my $date = $c->stash->{form_date} = $c->param('postDate'); + my $content = $c->stash->{form_content} = $c->param('postContent'); + + my $jekyll = $c->jekyll($blog->domain->name); + my $post = $c->stash->{post} = $jekyll->get_post( $c->param('mdfile') ); + + $post->markdown( $content ); + $post->headers->{title} = $title; + $post->headers->{date} = $date; + + $jekyll->write_post( $post ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Updated $title!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); +} + +sub blog_post ( $c ) { + my $blog = $c->stash->{blog}; +} + +sub _make_slug ( $date, $title ) { + + my $slug; + + if ( $date =~ /^(\d{4}-\d{2}-\d{2})/ ) { + $slug = $1; + } + + s/[^a-zA-Z0-9_-]+/-/g, s/^[^a-zA-Z0-9]+//, s/[^a-zA-Z0-9]+$// for $title; + + $slug .= "-$title.markdown"; + + return $slug; + +} + +sub do_blog_post ( $c ) { + my $blog = $c->stash->{blog}; + + my $title = $c->stash->{form_title} = $c->param('postTitle'); + my $date = $c->stash->{form_date} = $c->param('postDate'); + my $content = $c->stash->{form_content} = $c->param('postContent'); + + my $jekyll = $c->jekyll($blog->domain->name); + + + my $post = $c->stash->{post} = $jekyll->new_post( _make_slug( $date, $title ) ); + + $post->markdown( $content ); + $post->headers->{title} = $title; + $post->headers->{date} = $date; + $post->headers->{layout} = 'post'; + + $jekyll->write_post( $post ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Created $title!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); +} + +sub blog_settings ($c) { + my $blog = $c->stash->{blog}; + + my $data = $c->jekyll($blog->domain->name)->config->data; + + my $title = $c->stash->{form_title} = $data->{title}; + my $desc = $c->stash->{form_desc} = $data->{description}; + my $email = $c->stash->{form_email} = $data->{email}; +} + +sub do_blog_settings ($c) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + + my $title = $c->stash->{form_title} = $c->param( 'configTitle' ); + my $desc = $c->stash->{form_desc} = $c->param( 'configDesc' ); + my $email = $c->stash->{form_email} = $c->param( 'configEmail' ); + + $jekyll->config->data->{title} = $title; + $jekyll->config->data->{description} = $desc; + $jekyll->config->data->{email} = $email; + + $jekyll->write_config; + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "The settings have been updated!!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_settings', { id => $blog->id } ) ); +} + +sub blog_config ( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + my $config = $jekyll->config; + + my $config_text = $c->stash->{form_config} = $config->as_text; +} + +sub do_blog_config ( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + my $config = $jekyll->config; + + my $config_text = $c->stash->{form_config} = $c->param( 'blogConfig' ); + + $config->set_from_text( $config_text ); + + $jekyll->write_config; + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "The config has been updated!!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_config', { id => $blog->id } ) ); +} + +sub blog_builds ( $c ) { + my $blog = $c->stash->{blog}; + +} + +sub blog_media ( $c ) { + my $blog = $c->stash->{blog}; + + my $media_files = $c->stash->{media_files} = $c->jekyll($blog->domain->name)->list_media; +} + +sub do_blog_media_remove( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + my $media_file = Mojo::File->new( $jekyll->repo_path . "/assets/media/" . $c->param('file') ); + + if ( $media_file->stat ) { + $jekyll->remove_file( $media_file->to_string, "Removed media file" . $media_file->basename ); + } + + $c->sync_blog_media( $blog ); + + $c->flash( confirmation => "Removed " . $media_file->basename ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_media', { id => $blog->id } ) ); + +} + +sub do_blog_media ( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + + my $upload = $c->req->upload( 'upload' ); + + if ( ! $upload->asset->size ) { + $c->flash( error_message => "You must select a file to upload" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_media', { id => $blog->id } ) ); + return; + } + + # Ensure the upload directory exists. + Mojo::File->new( $jekyll->repo_path . "/assets/media/" )->make_path; + + # Move the file there + $upload->move_to( $jekyll->repo_path . "/assets/media/" . $upload->filename ); + + $jekyll->commit_file( + $jekyll->repo_path . "/assets/media/" . $upload->filename, + "Add media " . $upload->filename + ); + + $c->sync_blog_media( $blog ); + + $c->flash( confirmation => "Uploaded file!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_media', { id => $blog->id } ) ); +} + +sub blog_history ( $c ) { + my $blog = $c->stash->{blog}; + + my $history = $c->stash->{history} = $c->jekyll($blog->domain->name)->history; +} + +sub do_blog_history ( $c ) { + my $blog = $c->stash->{blog}; + + my $commit = $c->param('commit_hash'); + + my $jekyll = $c->jekyll($blog->domain->name); + + my $history = $c->stash->{history} = $jekyll->history; + + my ( $old_commit ) = grep { $_->{commit} eq $commit } @{$history}; + + if ( $old_commit ) { + $jekyll->revert_commit( $commit ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Undid $commit!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_history', { id => $blog->id } ) ); + } +} + +sub blog_pages ( $c ) { + my $blog = $c->stash->{blog}; + + my $blog_pages = $c->stash->{blog_pages} = [ map { $_->read } @{$c->jekyll($blog->domain->name)->list_pages} ]; +} + +sub blog_page_edit ( $c ) { + my $blog = $c->stash->{blog}; + + # This is a dumb-expensive way of loading the file. TODO, fix this. + my $blog_pages = $c->stash->{blog_pages} = [ map { $_->read } @{$c->jekyll($blog->domain->name)->list_pages} ]; + + my $rel_path = $c->param('file'); + + ( $c->stash->{blog_page} ) = grep { $_->rel_path eq $rel_path } @{$blog_pages}; + + if ( ! $c->stash->{blog_page} ) { + $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); + } + +} + +sub do_blog_page_remove ( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + + my $blog_pages = $c->stash->{blog_pages} = [ map { $_->read } @{$jekyll->list_pages} ]; + + my $rel_path = $c->param('file'); + + my ( $page ) = grep { $_->rel_path eq $rel_path } @{$blog_pages}; + + $jekyll->remove_markdown_file( $page ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "That page has been removed." ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); +} + +sub do_blog_page_edit ( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + + # This is a dumb-expensive way of loading the file. TODO, fix this. + my $blog_pages = $c->stash->{blog_pages} = [ map { $_->read } @{$jekyll->list_pages} ]; + + my $rel_path = $c->param('file'); + my $content = $c->param('pageContent'); + my $headers = $c->param('pageHeaders'); + + my ( $blog_page ) = grep { $_->rel_path eq $rel_path } @{$blog_pages}; + + if ( ! $blog_page ) { + $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); + return; + } + + $blog_page->set_headers_from_string( $headers ); + $blog_page->markdown( $content ); + + $jekyll->write_post( $blog_page ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Updated Page " . $blog_page->filename . "!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); +} + +sub do_blog_post_alter ( $c ) { + my $blog = $c->stash->{blog}; + + my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); + + my $content = $c->param('postContent'); + my $headers = $c->param('postHeaders'); + + $post->set_headers_from_string( $headers ); + $post->markdown( $content ); + + $c->jekyll($blog->domain->name)->write_post( $post ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Updated Post " . $post->headers->{title} . "!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); +} + +sub blog_page ( $c ) { + my $blog = $c->stash->{blog}; +} + +sub do_blog_page ( $c ) { + my $blog = $c->stash->{blog}; + + my $path = $c->param('pagePath'); + my $content = $c->param('pageContent'); + my $headers = $c->param('pageHeaders'); + + my $jekyll = $c->jekyll($blog->domain->name); + + my $page = $jekyll->new_page( "/$path.markdown" ); + + $page->set_headers_from_string( $headers ); + $page->markdown( $content ); + + $jekyll->write_post( $page ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Created Page " . $page->filename . "!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); +} + +1; diff --git a/Web/templates/admin/_nav.html.ep b/Web/templates/admin/_nav.html.ep new file mode 100644 index 0000000..8f97f32 --- /dev/null +++ b/Web/templates/admin/_nav.html.ep @@ -0,0 +1,32 @@ + + +