diff --git a/app/App.php b/app/App.php index 5793a9c..4d6b148 100644 --- a/app/App.php +++ b/app/App.php @@ -13,6 +13,7 @@ use Sikofitt\Config\ConfigTrait; use Sikofitt\Json\JsonFileTrait; use Sikofitt\Json\JsonTrait; use Silex\Application; +use Symfony\Component\HttpFoundation\Request; require __DIR__ . '/../vendor/autoload.php'; diff --git a/app/config/config.yml b/app/config/config.yml index 68821c5..dd25dca 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -1,7 +1,7 @@ # This file is auto-generated during the composer install app: - debug: false - environment: prod + debug: true + environment: dev title: 'R. Eric Wheeler | Resume' email: eric@rewiv.com phone: 510-646-2135 diff --git a/app/themes/default/awards.html.twig b/app/themes/default/awards.html.twig new file mode 100644 index 0000000..e69de29 diff --git a/app/themes/default/base.html.twig b/app/themes/default/base.html.twig index f5c3359..9d6cc17 100644 --- a/app/themes/default/base.html.twig +++ b/app/themes/default/base.html.twig @@ -12,25 +12,32 @@ {% block apple_meta %} {# #} {% endblock %} - + + {% block stylesheets %}{% endblock %} {% block inline_styles %}{% endblock %} - - - - - + + + + + {% block javascripts_head %}{% endblock %} {% block inline_js_head %}{% endblock %} -
+
{% block body %} {% endblock %}
- + + {% block javascripts_foot %}{% endblock %} {% block inline_js_foot %}{% endblock %} diff --git a/app/themes/default/education.html.twig b/app/themes/default/education.html.twig new file mode 100644 index 0000000..e69de29 diff --git a/app/themes/default/index.html.twig b/app/themes/default/index.html.twig index c290450..4cd6d17 100644 --- a/app/themes/default/index.html.twig +++ b/app/themes/default/index.html.twig @@ -1,272 +1,161 @@ {% extends 'base.html.twig' %} {% block title %} - {{ app.config.app.title | default('Resume') }} + {{ app.config.app.title | default('Resume') }} {% endblock %} {% block body %} + +
+
+

+ {% if basics.name is not empty %} + {{ basics.name|title }} + {% else %} + {{ app.config.app.title|default('Resume') }} + {% endif %} + {% if basics.label is not empty %} + {{ basics.label }} + {% endif %} +

+
+ {% if basics.summary is not empty %} +

{{ basics.summary|raw }}

+ {% endif %} + +
+
+ +
+
+ {% include 'skills.html.twig' %} + {% include 'work.html.twig' %} + {% include 'references.html.twig' %} +
+
+ -
+ -
-
-

Experience

-
- -
- {% for position in work %} -

- {{ position.company }} - - {{ position.startDate|date('M, Y') }} - - {% if position.endDate is not defined %} - Current - {% else %} - {{ position.endDate|date('M, Y') }} - {% endif %} - - (~ - {% if position.endDate is not defined %} - {{ position.startDate|date_diff }} - {% else %} - {{ position.startDate|date_diff(position.endDate) }} - {% endif %} - ) - -

-
{{ position.position }}
-

- {{ position.summary|raw }} -

- {% if position.highlights is defined and position.highlights is not empty %} -
-
Highlights
- {% for highlight in position.highlights %} -
{{ highlight|raw }} {# raw is deprecated in 2.0 #}
- {% endfor %} -
- {% endif %} -
- {% endfor %} - -
-
- -
- -
- -
- - -
- -
-

Contact

- -
    - - {% if app.config.app.phone is not empty %} - -
  • Phone
  • - {% endif %} - -
  • - {% if basics.email is not empty %} - {{ basics.email }} - {% endif %} - -
  • - - {% if basics.website is not empty %} -
  • {{ basics.website }}
  • - {% endif %} - {% if basics.location|length > 0 and basics.location is not empty %} -
  • -
    - {% set location = basics.location %} - - {% if location.address is not empty %} - {{ location.address }}
    - {% endif %} - {% if location.city is not empty %} - {{ location.city }}, - {% endif %} - {% if location.region is not empty %} -  {{ location.region }}, - {% endif %} - {% if location.countryCode is not empty %} -  {{ location.countryCode }} - {% endif %}
    - -
    -
  • - {% endif %} -
  • - {% for profile in basics.profiles %} - {{ render_profile(profile)|raw }} - {% endfor %} - -
  • -
  • -
- {% if skills is defined and skills is not empty %} - -

Skills

- -
- {% for skill in skills %} -
{{ skill.name }}
-
{{ skill.keywords|join(', ')|raw }}
- {% endfor %} -
+ {% if basics.website is not empty %} +
  • + {{ basics.website }} +
  • + {% endif %} + {% if basics.location|length > 0 and basics.location is not empty %} +
  • +
    + {% set location = basics.location %} + {% if location.address is not empty %} + {{ location.address }}
    {% endif %} - - -
  • - - -
    - -
    -
    -
    - - -
    - -
    -
    - {{ form_start(contact_form) }} - -
    - Contact {% if basics.email is not empty %} - {{ basics.email }}{% endif %} -
    - {{ form_label(contact_form.name) }} -
    - {{ form_widget(contact_form.name) }} -
    -
    -
    - {{ form_label(contact_form.email) }} -
    - {{ form_widget(contact_form.email) }} -
    -
    -
    - {{ form_label(contact_form.message|raw) }} -
    - {{ form_widget(contact_form.message) }} -
    -
    -
    - {{ form_label(contact_form.submit) }} -
    - {{ form_widget(contact_form.submit) }} -
    -
    - {{ form_rest(contact_form) }} -
    - {{ form_end(contact_form) }} -
    -
    -
    -
    -
    - - - -
    -
    - - -
    - -
    -

    Verify

    -
    -

    Verify that you are a human please.

    -
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
      - {% if basics.email is not empty %} -
    • {{ basics.email }}
    • + {% if location.city is not empty %} + {{ location.city }}, {% endif %} - {% if basics.phone is not empty %} -
    • {{ basics.phone }}
    • + {% if location.region is not empty %} +  {{ location.region }}, {% endif %} - {% if basics.location|length > 0 and basics.location is not empty %} -
    • -
      - {% for location in basics.location %} - {% if location.address is not empty %} - {{ location.address }}
      - {% endif %} - {% if location.city is not empty %} - {{ location.city }} - {% if location.postalCode is not empty %} -  {{ location.postalCode }} - {% endif %} - {% if location.countryCode is not empty %} -  {{ location.countryCode }} - {% endif %}
      - {% endif %} - {% endfor %} -
      -
    • - {% endif %} -
    • + {% if location.countryCode is not empty %} +  {{ location.countryCode }} + {% endif %}
      + + +
    • + {% endif %} +
    • + {% for profile in basics.profiles %} + {{ render_profile(profile)|raw }} + {% endfor %} + +
    • + +
    + +
    + - - -
    -
    -
    -

    Sending message ... - -

    -
    + +
    + {% include 'contact.html.twig' %} + + + {% include 'phone.html.twig' %} + +
    +
    +
      + {% if basics.email is not empty %} +
    • {{ basics.email }}
    • + {% endif %} + {% if basics.phone is not empty %} +
    • {{ basics.phone }}
    • + {% endif %} + {% if basics.location|length > 0 and basics.location is not empty %} +
    • +
      + {% for location in basics.location %} + {% if location.address is not empty %} + {{ location.address }}
      + {% endif %} + {% if location.city is not empty %} + {{ location.city }} + {% if location.postalCode is not empty %} +  {{ location.postalCode }} + {% endif %} + {% if location.countryCode is not empty %} +  {{ location.countryCode }} + {% endif %}
      + {% endif %} + {% endfor %} +
      +
    • + {% endif %} +
    • + +
    • +
    +
    +
    +
    +

    Sending message ... + +

    +
    +
    {% endblock %} + {% block javascripts_foot %} - + {% endblock %} diff --git a/app/themes/default/interests.html.twig b/app/themes/default/interests.html.twig new file mode 100644 index 0000000..e69de29 diff --git a/app/themes/default/languages.html.twig b/app/themes/default/languages.html.twig new file mode 100644 index 0000000..e69de29 diff --git a/app/themes/default/publications.html.twig b/app/themes/default/publications.html.twig new file mode 100644 index 0000000..e69de29 diff --git a/app/themes/default/references.html.twig b/app/themes/default/references.html.twig new file mode 100644 index 0000000..3e81bd0 --- /dev/null +++ b/app/themes/default/references.html.twig @@ -0,0 +1,12 @@ +{% if references is defined and references is not empty %} +

    References

    +
    + {% for reference in references %} +
    +

    {{ reference.reference|raw }}

    + {{ reference.name }} +
    + {% endfor %} + + {% endif %} +
    \ No newline at end of file diff --git a/app/themes/default/skills.html.twig b/app/themes/default/skills.html.twig new file mode 100644 index 0000000..2d26276 --- /dev/null +++ b/app/themes/default/skills.html.twig @@ -0,0 +1,13 @@ +{% if skills is defined and skills is not empty %} + +

    Skills

    +
    + {% for skill in skills %} +
    {{ skill.name }}
    + +
    {{ skill.keywords|join(', ') }}
    + + {% endfor %} +
    + +{% endif %} \ No newline at end of file diff --git a/app/themes/default/volunteer.html.twig b/app/themes/default/volunteer.html.twig new file mode 100644 index 0000000..e69de29 diff --git a/app/themes/default/work.html.twig b/app/themes/default/work.html.twig new file mode 100644 index 0000000..d7896f4 --- /dev/null +++ b/app/themes/default/work.html.twig @@ -0,0 +1,41 @@ +

    Experience

    +
    + +
    + {% for position in work %} +

    + {{ position.company }} + + {{ position.startDate|date('M, Y') }} - + {% if position.endDate is not defined %} + Current + {% else %} + {{ position.endDate|date('M, Y') }} + {% endif %} + + (~ + {% if position.endDate is not defined %} + {{ position.startDate|date_diff }} + {% else %} + {{ position.startDate|date_diff(position.endDate) }} + {% endif %} + ) + +

    +
    {{ position.position }}
    +

    + {{ position.summary|raw }} +

    + {% if position.highlights is defined and position.highlights is not empty %} +
    +
    Highlights
    + {% for highlight in position.highlights %} +
    {{ highlight|raw }} {# raw is deprecated in 2.0 #}
    + {% endfor %} +
    + {% endif %} +
    + {% endfor %} + +
    +
    \ No newline at end of file diff --git a/bin/console b/bin/console index bc903bb..c5a445e 100755 --- a/bin/console +++ b/bin/console @@ -36,5 +36,6 @@ $application->add(new SchemaValidationCommand()); $application->add($twigDebugCommand); $application->add($twigLintCommand); $application->add(new \Symfony\CS\Console\Command\FixCommand()); +$application->add(new Sikofitt\Command\CreatePdfCommand()); $application->run($input); diff --git a/data/resume.json b/data/resume.json index abe5d0e..f4077ca 100644 --- a/data/resume.json +++ b/data/resume.json @@ -1,133 +1,169 @@ { - "basics": { - "name": "R. Eric Wheeler", - "label": "Developer / Systems", - "picture": "http://rewiv.com/storage/me.png", - "email": "eric@ericwheeler.net", - "phone": "", - "website": "https://code.reric.me", - "summary": "My name is Eric Wheeler. I enjoy programming, working on computer hardware/electronics, music and gardening.", - "location": { - "address": "", - "postalCode": "CA 94578", - "city": "San Leandro", - "countryCode": "US", - "region": "California" - }, - "profiles": [ - { - "network": "Twitter", - "username": "sikofitt", - "url": "https://twitter.com/sikofitt" - }, - { - "network": "Github", - "username": "sikofitt", - "url": "" - }, - { - "network": "Gitlab", - "username": "sikofitt", - "url": "https://repos.bgemi.net/u/sikofitt" - }, - { - "network": "linkedin", - "username": "reric", - "url": "https://www.linkedin.com/in/reric" - } - ] + "basics": { + "name": "R. Eric WHeeler", + "label": "Developer / Systems", + "picture": "http://rewiv.com/storage/me.png", + "email": "eric@ericwheeler.net", + "phone": "510-646-2135", + "website": "http://rewiv.com", + "summary": "My name is Eric Wheeler.
    I enjoy programming, working on computer hardware/electronics, music and gardening. My computer experience dates back to the Apple II/e. I enjoy learning in general, although my focus is mainly on new technologies. I have excellent problem solving skills, I adapt well to new things, and learn very quickly.", + "location": { + "address": "", + "postalCode": "94578", + "city": "San Leandro", + "countryCode": "US", + "region": "California" }, - "work": [ - { - "company": "Stanford University", - "position": "Developer / Systems Administrator", - "website": "https://ee.stanford.edu", - "startDate": "2007-05-27", - "summary": "I have done many different things during my employment at Stanford University.
    A few of things things have been : Desktop Support, Computer cluster administration for the NSF and NNIN using Scyld Clusterware, General programing/debugging and frontend as well as backend web development using a number of different technologies.", - "highlights": [ - "Repaired and Maintained a 64 node research computing cluster for the NNIN funded by the NSF.", - "Converted Electrical Engineering's static web site to Drupal 7.", - "Created many Drupal 7 modules for the EE website including a custom events, lecture and committe minutes content type, a CDN module for uploading and recieving images/videos/documents, an Orglist module for displaying Faculty, Students, and Staff from a custom API.", - "Created a custom Drupal 7 site for the SystemX organization with integrated login for affiliates as well as Stanford staff." - ] - }, - { - "company": "Searchathlon INC.", - "position": "Web Developer / Linux System Administration", - "website": "http://searchathlon.com", - "startDate": "2005-01-01", - "endDate": "2006-01-01", - "summary": "", - "highlights": [] - } - ], - "volunteer": [], - "education": [], - "awards": [], - "publications": [], - "skills": [ - { - "name": "Web Development / Design", - "level": "", - "keywords": [ - "HTML5", - "CSS3", - "Javascript", - "jQuery", - "NPM", - "Bower", - "Grunt", - "Let's Encrypt" - ] - }, - { - "name": "PHP", - "level": "", - "keywords": [ - "PHP5", - "PHP7", - "Drupal 7", - "Symfony 2", - "Symfony 3", - "OOP", - "Silex", - "Slim", - "Doctrine", - "Composer" - ] - }, - { - "name": "PHP", - "level": "", - "keywords": [ - "PHP5", - "PHP7", - "Symfony 2", - "Symfony 3", - "OOP", - "Silex", - "Slim", - "Doctrine", - "Composer" - ] - } - - ], - "languages": [], - "interests": [ - { - "name": "Computers", - "keywords": [ - "Hardware", - "Programming", - "Design" - ] - } - ], - "references": [ - { - "name": "Erlich Bachman", - "reference": "It is my pleasure to recommend Richard, his performance working as a consultant for Main St. Company proved that he will be a valuable addition to any company." - } + "profiles": [ + { + "network": "Twitter", + "username": "sikofitt", + "url": "https://twitter.com/sikofitt" + }, + { + "network": "Github", + "username": "sikofitt", + "url": "https://github.com/sikofitt" + }, + { + "network": "Gitlab", + "username": "sikofitt", + "url": "https://repos.bgemi.net/u/sikofitt" + }, + { + "network": "linkedin", + "username": "reric", + "url": "https://www.linkedin.com/in/reric" + } ] -} + }, + "work": [ + { + "company": "Stanford University", + "position": "Developer / System Administrator", + "website": "https://ee.stanford.edu", + "startDate": "2007-05-27", + "summary": "I have done many different things during my employment at Stanford University.
    A few of things things have been : Desktop Support, Computer cluster administration for the NSF and NNIN using Scyld Clusterware, General programing/debugging and frontend as well as backend web development using a number of different technologies.", + "highlights": [ + "Repaired and Maintained a 64 node research computing cluster for the NNIN funded by the NSF.", + "Converted Electrical Engineering's static web site to Drupal 7.", + "Created many Drupal 7 modules for the EE website including a custom events, lecture and committe minutes content type, a CDN module for uploading and recieving images/videos/documents, an Orglist module for displaying Faculty, Students, and Staff from a custom API.", + "Created a custom Drupal 7 site for the SystemX organization with integrated login for affiliates as well as Stanford staff." + ] + }, + { + "company": "Searchathlon", + "position": "Web Developer / Linux System Administrator", + "startDate": "2005-01-01", + "endDate": "2007-01-01", + "summary": "Searchathlon was a search startup for media. My main duties were administrating a Linux server running Fedora core 3 and web maintenance/development using Apache. Other duties included managing Apache and IIS web servers on a Windows 2000 setup.", + "highlights": [ + "Created a working Apache/ Microsoft ASP (Active Server Pages) setup on Fedora Core Linux version 3 using a CGI (Common Gateway Interface) setup." + ] + } + ], + "volunteer": [], + "education": [], + "awards": [], + "publications": [], + "skills": [ + { + "name": "Web Development / Design (Back end)", + "level": "", + "keywords": [ + "NPM", + "Bower", + "GruntJS", + "Let's Encrypt", + "MySQL", + "PostgresSQL", + "JSON", + "XML", + "Apache 2.2/2.4", + "Nginx", + "Pound web proxy", + "Deployment (Heroku, Dokku)", + "Virtualization (Virtualbox / VMWare, Vagrant)" + ] + }, + { + "name": "Web Development / Design (Front end)", + "level": "", + "keywords": [ + "HTML 4/5", + "CSS 2/3", + "Javascript", + "jQuery" + ] + }, + { + "name": "PHP", + "level": "", + "keywords": [ + "PHP 5.3-5.6 / 7", + "Composer", + "Symfony 2 / 3", + "Silex 1 / 2", + "Slim 2 / 3", + "Doctrine" + ] + }, + { + "name": "General Programing", + "level": "", + "keywords": [ + "OOP", + "Turbo Pascal / Free Pascal", + "Python", + "C++", + "C", + "Perl" + ] + }, + { + "name": "System Administration", + "level": "", + "keywords": [ + "Linux (Gentoo, Centos/Red Hat/Debian/Ubuntu)", + "Mac OS/X", + "Solaris 10/11", + "Windows XP / 7 / 8 / 8.1 / 10 / 2000 / 2003", + "Bash", + "ZSH", + "Penguin Computing Scyld ClusterWare HPC (High Performance Computing)", + "Source Code Building (auto-tools, auto-make, auto-conf)", + "MS-DOS 5-7 / FreeDOS", + "FTP", + "SFTP/SSH", + "Log debugging", + "Network debugging" + ] + } + ], + "languages": [ + { + "language": "English", + "fluency": "Native" + } + ], + "interests": [ + { + "name": "Computers", + "keywords": [ + "Hardware", + "Programming", + "Design" + ] + } + ], + "references": [ + { + "name": "Craig Stadler", + "reference": "It is my pleasure to recommend Richard, his performance working as a consultant for Main St. Company proved that he will be a valuable addition to any company." + }, + { + "name": "John Doe", + "reference": "Richard is awesome and cool." + } + ] +} \ No newline at end of file diff --git a/src/Sikofitt/Command/CreatePdfCommand.php b/src/Sikofitt/Command/CreatePdfCommand.php new file mode 100644 index 0000000..72f9be3 --- /dev/null +++ b/src/Sikofitt/Command/CreatePdfCommand.php @@ -0,0 +1,56 @@ +setName('resume:pdf:create') + ->setDescription('Create a pdf of your website.') + ->setProcessTitle('PDF Creation'); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + */ + public function interact (InputInterface $input, OutputInterface $output) + { + $index = $this->getSilexApplication()->renderView('index.html.twig', ['renderPdf' => true]); + $pdf = new Pdf($this->getSilexApplication()->getRootDirectory() . '/vendor/bin/wkhtmltopdf-amd64'); + $pdf->generateFromHtml($index, $this->getSilexApplication()->getRootDirectory() . '/resume.pdf', ['keep-relative-links' => false, 'resolve-relative-links' => false, 'load-error-handling' => false, 'disable-javascript' => true, 'disable-external-links' => true, 'disable-internal-links' => true]); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + */ + public function execute (InputInterface $input, OutputInterface $output) + { + + } + +} \ No newline at end of file diff --git a/src/Sikofitt/Controller/ResumeControllerProvider.php b/src/Sikofitt/Controller/ResumeControllerProvider.php index 944aa2d..f6f68a4 100644 --- a/src/Sikofitt/Controller/ResumeControllerProvider.php +++ b/src/Sikofitt/Controller/ResumeControllerProvider.php @@ -19,6 +19,8 @@ use Symfony\Component\Form\Form; use Symfony\Component\Form\FormFactory; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Knp\Snappy\Pdf; +use Symfony\Component\HttpFoundation\Response; /** * Class ResumeControllerProvider @@ -45,11 +47,39 @@ class ResumeControllerProvider implements ControllerProviderInterface $contactForm = $app['form.factory']->create(ContactType::class); $controllers = $app['controllers_factory']; + $controllers->get('/pdf', function (Request $request) use ($app) { + $pdf = new Pdf($app->getRootDirectory() . '/vendor/bin/wkhtmltopdf-amd64'); + $content = $app->render('index.html.twig', [ + 'renderPdf' => true, + 'baseUrl' => $request->getSchemeAndHttpHost(), + 'fullData' => $this->resumeData, + 'basics' => $this->getResumeBasics(), + 'work' => $this->getResumeWork(), + 'volunteer' => $this->getResumeVolunteer(), + 'education' => $this->getResumeEducation(), + 'awards' => $this->getResumeAwards(), + 'publications' => $this->getResumePublications(), + 'skills' => $this->getResumeSkills(), + 'languages' => $this->getResumeLanguages(), + 'interests' => $this->getResumeInterests(), + 'references' => $this->getResumeReferences(), + ]); + $renderedPdf = $pdf->getOutputFromHtml($content->getContent()); + + $response = new Response(); + $response->setContent($renderedPdf); + $response->setStatusCode(200); + $response->headers->set('Content-Type', 'application/pdf'); + $response->headers->set('Content-Disposition', 'attachment; filename="resume.pdf'); + return $response; + }); $controllers->get('/', function (Request $request) use ($app, $contactForm) { + return $app['twig']->render('index.html.twig', [ - + 'renderPdf' => false, + 'baseUrl' => $request->getSchemeAndHttpHost(), 'fullData' => $this->resumeData, 'basics' => $this->getResumeBasics(), 'work' => $this->getResumeWork(), diff --git a/src/Sikofitt/js/resume.js b/src/Sikofitt/js/resume.js index cca0182..8476c7b 100644 --- a/src/Sikofitt/js/resume.js +++ b/src/Sikofitt/js/resume.js @@ -1,7 +1,7 @@ jq = jQuery.noConflict(); jq(document).ready(function (jq) { - jq('form#recaptcha').on('submit', function (event) { + jq('form#phone-recaptcha').on('submit', function (event) { event.stopImmediatePropagation(); event.stopPropagation(); jq.post(jq(this).attr('action'), jq(this).serialize(), function (response) { @@ -28,7 +28,7 @@ jq(document).ready(function (jq) { phone.attr('href', 'tel:' + data.message.phone); phone.text(data.message.phone); divRoot.append(h1); - jq('#recaptcha-wrapper').replaceWith(divRoot); + jq('#phone-recaptcha-wrapper').replaceWith(divRoot); } });