Juampy NR - @juampynr
Give the design and front end teams freedom to craft the website without the constraints of a CMS
$ drush queue-list
Queue Items Class
file_entity_type_determine 0 SystemQueue
lullabot_edit_exporter_nodes 1 SystemQueue
lullabot_edit_exporter_views 0 SystemQueue
lullabot_edit_exporter_lanyrd 0 SystemQueue
lullabot_edit_exporter_latest_articles 0 SystemQueue
lullabot_edit_exporter_weather 0 SystemQueue
$ drush queue-run lullabot_edit_exporter_nodes
function _lullabot_edit_exporter_nodes_run($nid) {
$sag = _lullabot_edit_exporter_get_couchdb_handler();
// ...
switch ($result['op']) {
case 'update':
$node = node_load($nid);
if ($node) {
$output = new stdClass();
$output->_id = $node->uuid;
// Allow other modules to determine the output class structure.
module_invoke_all('lullabot_edit_exporter_node_' . $node->type, $node, $output);
module_invoke_all('lullabot_edit_exporter_node', $node, $output);
// Insert/Update the node into couchdb.
try {
if ($sag->put($output->_id, $output)->body->ok) {
$success = TRUE;
}
}
catch (Exception $e) {
watchdog('lullabot_edit_exporter', $e->getMessage(), array(), WATCHDOG_WARNING);
}
// ...
}
function lullabot_edit_article_lullabot_edit_exporter_node_article($node, $output) {
$node_wrapper = entity_metadata_wrapper('node', $node);
$output->nid = $node->nid;
$output->type = $node->type;
$output->title = $node->title;
$output->published = $node->created;
$output->full_slug = _lullabot_edit_shared_fields_get_full_slug($node);
$output->full_slug_flat = _lullabot_edit_shared_fields_get_flat_slug($output->full_slug);
$output->legacy_nid = $node_wrapper->field_legacy_nid->value();
$output->deck = _lullabot_edit_exporter_filter_xss($node_wrapper->field_deck->raw());
$output->body = array(
'value' => $node_wrapper->body->value() ? $node_wrapper->body->value->value() : NULL,
'format' => $node_wrapper->body->value() ? $node_wrapper->body->format->value() : NULL,
);
$output->related_links = array();
foreach ($node_wrapper->field_related_links->getIterator() as $delta => $item_wrapper) {
$output->related_links[] = array(
'url' => $item_wrapper->url->value(),
'title' => $item_wrapper->title->value(),
);
}
// ...
}
// First we have declarations and dependencies being loaded.
'use strict';
var React = require('react');
var Settings = require('../../../settings');
var Header = require('../component/header.jsx');
// Then the component definition.
var LayoutArticle = React.createClass({
// The class may have custom methods:
getBackground: function() {},
getSeries: function() {},
// React's component lifecycle offers a few events:
getInitialState: function() {},
componentDidMount: function() {},
// The render() method returns a mix of HTML and XML that is then compiled.
render: function() {
var activeAuthors = [];
this.props.doc.authors.map(function(author) {
if (author.active) {
activeAuthors.push(author);
}
});
return (
);
}
});
// Finally, export the React component as a NodeJS module.
module.exports = LayoutArticle;
'use strict';
var React = require('react');
var Icon = require('./../icon.jsx');
var PromoNewsletter = React.createClass({
getInitialState: function() {
return {
sending: false,
status: null,
tryAgain: false
};
},
tryAgain: function (event) {
event.preventDefault();
this.setState({sending: false, status: '', tryAgain: false});
},
handleSubmit: function (event) {
event.preventDefault();
this.email = React.findDOMNode(this.refs.email).value;
if (this.email) {
var url = '/mailchimp-signup';
this.setState({sending: true, status: '', tryAgain: false});
var xmlhttp = new XMLHttpRequest();
var _this = this;
// Handle network errors.
xmlhttp.onerror = function() {
_this.setState({sending: false, status: 'Sorry, there has been a network error', tryAgain: true});
};
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
_this.setState({sending: false, status: '', tryAgain: false});
var response = JSON.parse(xmlhttp.responseText);
if (xmlhttp.status === 200) {
// Evaluate response and update status.
if (!response.error) {
_this.setState({sending: false, status: 'Success! Check your email for confirmation', tryAgain: false});
}
else {
switch (response.name) {
// Server errors.
case 'List_DoesNotExist':
case 'Invalid_ApiKey':
case 'User_InvalidRole':
_this.setState({sending: false, status: 'Oops, there is something wrong on our side. Please try again later', tryAgain: false});
break;
// Client errors.
case 'Email_NotExists':
case 'List_AlreadySubscribed':
case 'List_InvalidImport':
default:
_this.setState({sending: false, status: response.error, tryAgain: true});
break;
}
}
}
else {
// Handle server errors.
_this.setState({sending: false, status: 'Oops, there is something wrong on our side. Please try again later', tryAgain: false});
}
}
};
xmlhttp.open('POST', url, true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send('email=' + encodeURIComponent(this.email));
}
},
render: function() {
return (
Sign up for the Lullabot Newsletter and get our latest articles and more direct to your inbox
);
}
});
module.exports = PromoNewsletter;
'use strict';
var express = require('express');
var path = require('path');
var app = express();
var bodyParser = require('body-parser');
// ... Other routes go here ...
// Newsletter form handler.
app.use('/mailchimp-signup', function(req, res) {
var ServerSettings = require('../server-settings.js');
var Mcapi = require('mailchimp-api');
var mc = new Mcapi.Mailchimp(ServerSettings.mailChimp.apiKey);
mc.lists.subscribe({id: ServerSettings.mailChimp.listId, email: {email: req.body.email}}, function(data) {
res.send(data);
},
function(error) {
res.send(error);
});
});
echo "[TAG]: $TAG"
set -e
error() {
echo "Error detected: $@" 1>&2
exit 1
}
DRUSH=drush
# Set up the destination for the backup.
cd /var/www/edit.lullabot.com
OLD_TAG=`git describe --always --tag`
FILE=`date "+%Y-%m-%d-%H%M-$OLD_TAG.sql.gz"`
BACKUP_DIR="$HOME/drush-backups/pulls/edit.lullabot.com"
mkdir -p $BACKUP_DIR
BACKUP_FILE="$BACKUP_DIR/$FILE"
RESTORE_MSG="If problems were found, the database was saved to $BACKUP_FILE."
# Save a database backup.
cd docroot
eval "$DRUSH sql-dump | gzip > $BACKUP_FILE" &&
## Checkout the Git tag and update the database.
eval cd `eval $DRUSH dd` &&
eval git fetch origin &&
eval git checkout $TAG &&
eval $DRUSH -v updatepath ||
# If we end up here, there was a problem.
error "$RESTORE_MSG"
echo "$RESTORE_MSG"
echo "Cleaning up old dumps."
# Delete all but 4 most recent backups.
for x in `ls -tr $BACKUP_DIR | head -n -4`; do rm -v $BACKUP_DIR/$x; done
# Update the version number.
echo $TAG > version.txt
First, install dependencies:
echo "[TAG]: $GIT_TAG"
# Checks out the repository to a numbered directory.
mv $WORKSPACE/release /var/www/www.lullabot.com-releases/$BUILD_NUMBER
cd /var/www/www.lullabot.com-releases/$BUILD_NUMBER
# Copy .env settings.
cp /var/www/www.lullabot.com/.env .
# Build project dependencies and assets.
npm run update
npm run build
Then, update the web root's symlink:
# Point webroot to the new release through a symlink.
cd /var/www/
ln -s $WORKSPACE/$BUILD_NUMBER www.lullabot.com_tmp
mv -Tf www.lullabot.com_tmp www.lullabot.com
echo $GIT_TAG > www.lullabot.com/version.txt
# Restart the Node.js application.
sudo service lullabot.com-www restart
@juampynr
about.me/juampynr
Lullabot is looking for projects!