diff --git a/Changelog b/Changelog
index de602e8d..77c53a4b 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,46 @@
+1.2.9: 2017-11-13
+ * #3848: [ungleich] Optimize ungleich.ch landing page
+ * #3360: [ungleich] Ungleich.ch landing page animation fix
+ * #3421: [hosting] Signup form placeholder translations
+ * #3856: [ungleich] Glasfaser text modified
+ * bugfix: [blog] Redirect user to ungleich home on ungleich logo click
+ * #3858: [dcl] Change "affordable vm ..." text to "Ready in 30 seconds ..."
+1.2.8: 2017-10-21
+ * Remove ALLOWED_HOST alplora.ch
+ * Add ALLOWED_HOST hack4glarus.ch
+ * Fetch page_title and meta_description dynamically in glasfaser CMS template
+1.2.7: 2017-10-20
+ * Bugfix: [dcl, hosting] Fix Stripe js error in confirm payment page
+ * #3847: [ungleich] change text 'hosting products' -> 'our products'
+ * #3829: [dcl] Handle landing login fail in payment page itself
+ * #3794: [dcl, hosting] Update email styles
+ * #3828: [dcl, hosting] invoice period set to show monthly subscription
+ * #3838: [hosting] restyle signup/login/password reset/password pages
+ * Bugfix: [dg] Remove validate email link in the registration email
+ * Feature: [ungleich_page] Add new glasfaser CMS template
+1.2.6: 2017-10-10
+ * Bugfix: [dcl] Refactor and optimize images, links in glasfaser page
+ * Bugfix: [dcl] Fix email not being sent issue
+1.2.5: 2017-10-10
+ * #3785: [hosting] update 'my bills' page design
+ * Bugfix: [hosting] card details input form alignment fix
+ * #3823: [hosting] favicon link fixed
+ * #3844: [dcl] Add Glasfaser page for advertisement
+1.2.4: 2017-10-02
+ * #3780: [hosting] Store VM details locally
+ * #3764: [hosting] Show cancelled VMs' invoices
+ * #3736: [dcl] Refactor the place where we compute the VM price
+ * #3730: [dcl] Refactor price parameter passed in the DCL flow
+ * #3807: [dcl] Remove PricingView as it is no more used
+ * #3813: [hosting] JS error in create ssh key page
+ * #3756: [dcl] Update landing calculator and billing info page
+ * Bugfix: Fix PR 493 bug that creates a new StripeCustomer for each buying of VM with the same email id
+ * #3835: [all] Forbidden (403) CSRF verification failed issue.
+ * Bugfix: [hosting] Dashboard strictly available after login
+ * #3808: [dcl] Order confirmation page redesign
1.2.3: 2017-09-25
* #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email
- * #3731: [dcl, hosting] Added cdist ssh key handler
+ * #3731: [dcl, hosting] Added cdist ssh key handler
* #3628: [dcl] on hosting, VM is created at credit card info submit
* #3772: [dcl] Updated hosting app billing into monthly subscription and added new text and translations
* #3786: [hosting] Redesigned the hosting invoice and order-confirmation page
@@ -31,8 +71,8 @@
* #3765: [hosting] Text fix Your SSH Keys to My SSH Keys
* #3639: [datacenterlight] Added navbar menu after payment page on landing
* #3735: [hosting] Increased modal width and modal button width
- * #3709: Activated Text Plugin by default for the Page Title Text, enabled
tag text management
- * #3768: [datacenterlight, hosting] Fixed missing DE translation
+ * #3709: Activated Text Plugin by default for the Page Title Text, enabled tag text management
+ * #3768: [datacenterlight, hosting] Fixed missing DE translation
* #3678: [datacenterlight, hosting] Removed Lato font files
1.1.1: 2017-08-29
* #3709: [datacenterlight] Added faq tos cms template
@@ -77,7 +117,7 @@
1.0.22: 2017-07-30
* #3593: [datacenterlight] Removed underbars between social icons in index
* #3509: [datacenterlight, hosting] Made navbar transparent and removed mobile navbar bug in login/signup/reset-password
- * #3592: [datacenterlight] Changed “Order Now” button text to “Continue/weiter”
+ * #3592: [datacenterlight] Changed “Order Now” button text to “Continue/weiter”
* #3579: [datacenterlight] Removed “blinks” on click on navbar menus
* #3577: [datacenterlight] Added backend CPU, RAM, SSD fields validation
* #3615: [datacenterlight] Decoupled landing VM templates from OpenNebula
@@ -88,7 +128,7 @@
* #3629: [datacenterlight] Fixed navbar language switching bug
1.0.21: 2017-07-21
* #3591: [datacenterlight, payment] Fixed card holder name to appear on Confirm Order page
- * #3558: [datacenterlight] Changed font family and background color for header
+ * #3558: [datacenterlight] Changed font family and background color for header
* #3581: [datacenterlight] Lead font weight change
* #3584: [all] Add flag is_superuser=True in MyUserManager
1.0.20: 2017-07-18
@@ -160,14 +200,14 @@
1.0.5: 2017-06-06
* [all] General cleanup
* [datacenterlight] Add German translations
- * [datacenterlight] Change beta access to subscriptions
- * [hosting] Add German translations
+ * [datacenterlight] Change beta access to subscriptions
+ * [hosting] Add German translations
* [blog] Add German translation for header
* [opennebula_api] Improve testing, add ssh key functions
* [opennebula_api] Remove template views
- * [datacenterlight] Allow user to have multiple ssh keys
+ * [datacenterlight] Allow user to have multiple ssh keys
* [datacenterlight] Changed stripe.js v2 to v3
- * [datacenterlight] Added support for stripe payment errors on current user language
+ * [datacenterlight] Added support for stripe payment errors on current user language
1.0.4: 2017-06-05
* [all] Added new Domains to accept
1.0.3: 2017-06-02
@@ -179,6 +219,3 @@
* [datacenterlight] Fix initially shown price
1.0.0: 2017-05-25
* Initial stable release
-
- Next:
- [datacenterlight] Fixed credit card input issue
diff --git a/alplora/locale/de/LC_MESSAGES/django.po b/alplora/locale/de/LC_MESSAGES/django.po
index c39a4595..616ec68d 100644
--- a/alplora/locale/de/LC_MESSAGES/django.po
+++ b/alplora/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-05-30 13:47+0000\n"
+"POT-Creation-Date: 2017-10-10 21:35+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -18,137 +18,99 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: alplora/templates/alplora/contact.html:6
msgid "New message"
msgstr "Neue Nachricht"
-#: alplora/templates/alplora/contact.html:13
msgid "Name:"
msgstr "Name:"
-#: alplora/templates/alplora/contact.html:15
msgid "What is your name ?"
msgstr "Was ist Dein Name?"
-#: alplora/templates/alplora/contact.html:19
msgid "From:"
msgstr "Von:"
-#: alplora/templates/alplora/contact.html:21
msgid "You email"
msgstr "Deine Email"
-#: alplora/templates/alplora/contact.html:25
msgid "Message:"
msgstr "Nachricht:"
-#: alplora/templates/alplora/contact.html:27
msgid "Leave us your message"
msgstr "Schreibe hier Deine Nachricht"
-#: alplora/templates/alplora/contact.html:32
msgid "Close"
msgstr "schliessen"
-#: alplora/templates/alplora/contact.html:33
msgid "Send message"
msgstr "Nachricht senden"
-#: alplora/templates/alplora/contact_success.html:6
msgid "Message Sent"
msgstr "Nachricht gesendet"
-#: alplora/templates/alplora/contact_success.html:9
msgid "Thank you, we will contact you as soon as possible"
msgstr "Dankeschön! Wir melden uns sobald wie möglich!"
-#: alplora/templates/alplora/index.html:13
msgid "Find your animal anywhere, anytime"
msgstr "Finde deine Tiere"
-#: alplora/templates/alplora/index.html:99
-#: alplora/templates/alplora/index.html:463
msgid "About"
msgstr "Über"
-#: alplora/templates/alplora/index.html:102
-#: alplora/templates/alplora/index.html:248
-#: alplora/templates/alplora/index.html:469
msgid "Why Alplora?"
msgstr "Warum Alplora?"
-#: alplora/templates/alplora/index.html:105
-#: alplora/templates/alplora/index.html:466
msgid "Usecase"
msgstr ""
-#: alplora/templates/alplora/index.html:108
-#: alplora/templates/alplora/index.html:358
msgid "Testimonials"
msgstr "Referenzen"
-#: alplora/templates/alplora/index.html:111
-#: alplora/templates/alplora/index.html:423
-#: alplora/templates/alplora/index.html:477
msgid "Contact"
msgstr "Kontakt"
-#: alplora/templates/alplora/index.html:114
msgid "Login"
msgstr "Login"
-#: alplora/templates/alplora/index.html:137
msgid "Find your herd anytime, anywhere"
msgstr "Finde deine Herde jederzeit und überall"
-#: alplora/templates/alplora/index.html:138
msgid "Perfect fit for Swiss Alps"
msgstr "Perfekt für die Schweizer Alpen"
-#: alplora/templates/alplora/index.html:163
msgid "What is Alplora?"
msgstr "Was ist Alplora?"
-#: alplora/templates/alplora/index.html:164
msgid ""
"Alplora is an animal tracker made for outdoor grazing animals in Swiss Alps."
msgstr ""
"Alplora ist ein Sender, der speziell für Weidetiere in den Schweizer Alpen "
"entwickelt wurde."
-#: alplora/templates/alplora/index.html:165
msgid "Alplora is just like a cattle bell, but much better."
msgstr "Alplora ist wie eine Kuhglocke, nur viel besser."
-#: alplora/templates/alplora/index.html:174
msgid "LOST"
msgstr "VERLOREN"
-#: alplora/templates/alplora/index.html:176
msgid "When an animal gets separated from the herd and is lost."
msgstr "Wenn ein Tier sich von der Herde absondert und verloren geht."
-#: alplora/templates/alplora/index.html:184
msgid "WOLF"
msgstr "WOLF"
-#: alplora/templates/alplora/index.html:186
msgid "When a wolf gets close to the herd."
msgstr "Wenn ein Wolf sich der Herde nähert."
-#: alplora/templates/alplora/index.html:193
msgid "INJURED"
msgstr "VERLETZT"
-#: alplora/templates/alplora/index.html:195
msgid "When one of the animals is hurt."
msgstr "Wenn eins der Tiere verletzt ist."
-#: alplora/templates/alplora/index.html:205
msgid "How does Alplora track my animals?"
msgstr "Wie kann Alplora meine Tiere verfolgen und ausfindig machen ?"
-#: alplora/templates/alplora/index.html:206
msgid ""
"Each animal will be wearing a small tracker,and the tracker will be "
"sending a signal every 30 to 60 minutes."
@@ -156,33 +118,27 @@ msgstr ""
"Jedes Tier wird einen kleinen Sender tragen, welcher alle 30 bis 60 "
"Minuten ein Signal senden wird."
-#: alplora/templates/alplora/index.html:215
msgid "Access app"
msgstr "Zugang zur App"
-#: alplora/templates/alplora/index.html:217
msgid ""
"You can see the animal locations on a map by logging into our Alplora app."
msgstr ""
"Du kannst den Standort deiner Tiere jederzeit auf einer Karte verfolgen, "
"indem du dich in unsere Alplora App einloggst."
-#: alplora/templates/alplora/index.html:225
msgid "Get an alarm"
msgstr "Erhalte ein Warnsignal"
-#: alplora/templates/alplora/index.html:227
msgid ""
"When certain signals for danger are detected, Alplora sends an alarm to you."
msgstr ""
"Wenn Anzeichen von Gefahr bestehen, sendet dir die Alplora App einen "
"Warnsignal."
-#: alplora/templates/alplora/index.html:235
msgid "Find your animal"
msgstr "Finde deine Tiere"
-#: alplora/templates/alplora/index.html:238
msgid ""
"You can locate the animal in trouble on the realtime map and can take "
"actions for keeping the animal safe."
@@ -190,11 +146,9 @@ msgstr ""
"Du kannst dein Tier in Notsituationen auf einer Echtzeit-Karte lokalisieren "
"und hast die Möglichkeit es in Sicherheit zu bringen."
-#: alplora/templates/alplora/index.html:255
msgid "Perfect fit for Swiss mountains"
msgstr "Perfekt für die Schweizer Alpen"
-#: alplora/templates/alplora/index.html:257
msgid ""
"Alplora is made and tested for Swiss Alps. It is a perfect fit for Swiss "
"environment."
@@ -202,11 +156,9 @@ msgstr ""
"Alplora wurde speziell für die Schweizer Alpen entwickelt und vor Ort "
"getestet. Das Produkt passt perfekt in die Schweiz!"
-#: alplora/templates/alplora/index.html:263
msgid "Energy efficient"
msgstr "Energieeffizient"
-#: alplora/templates/alplora/index.html:265
msgid ""
"Alplora uses the latest wireless technology, our batteries last the whole "
"alp season."
@@ -214,11 +166,9 @@ msgstr ""
"Alplora arbeitet mit den neuesten Technologien, so dass der Akku die gesamte "
"Alpsaison überdauert."
-#: alplora/templates/alplora/index.html:271
msgid "Made with love"
msgstr "Mit Liebe gemacht"
-#: alplora/templates/alplora/index.html:273
msgid ""
"With a lot of love and respect for Swiss agriculture and nature, Alplora is "
"made by a Swiss company."
@@ -226,61 +176,49 @@ msgstr ""
"Alplora wurde mit viel Liebe und Respekt für die Schweizer Natur und "
"Landwirtschaft von einer Schweizer Firma entwickelt."
-#: alplora/templates/alplora/index.html:285
msgid "Who needs Alplora?"
msgstr "Wer benötigt Alplora?"
-#: alplora/templates/alplora/index.html:301
msgid " Are your animals..."
msgstr "Sind deine Tiere..."
-#: alplora/templates/alplora/index.html:304
msgid "sheep, goats, cows or llamas living freely in the Alps?"
msgstr "Schafe, Ziegen, Kühe oder Lamas, die frei in den Alpen leben?"
-#: alplora/templates/alplora/index.html:306
msgid "wearing bells?"
msgstr "solche, die Glocken tragen?"
-#: alplora/templates/alplora/index.html:308
msgid ""
"sometimes getting confused and going too far away from where they are "
"supposed to be?"
msgstr ""
"manchmal verwirrt und entfernen sich zu weit von ihrem vorgesehenen Standort?"
-#: alplora/templates/alplora/index.html:332
msgid "Do you..."
msgstr "Möchtest du..."
-#: alplora/templates/alplora/index.html:335
msgid "have animals which are staying outdoor during some time of the year?"
msgstr ""
"deine Tiere, die eine längere Zeit im Jahr unbeobachtet Draussen verbringen, "
"schützen und überwachen können?"
-#: alplora/templates/alplora/index.html:337
msgid "want to get an alarm when your animal is hurt, or in danger?"
msgstr ""
"alarmiert werden, wenn sich eines deiner Tiere verletzt oder in Gefahr "
"befindet ?"
-#: alplora/templates/alplora/index.html:339
msgid "want to see where your animals are on your cell phone map?"
msgstr ""
"mit deinem Smartphone auf einer Karte sehen können, wo sich deine Tiere "
"befinden? "
-#: alplora/templates/alplora/index.html:341
msgid "want to make sure 24/7 that your animals are safe?"
msgstr ""
"sicherstellen, dass sich deine Tiere rund um die Uhr in Sicherheit befinden?"
-#: alplora/templates/alplora/index.html:359
msgid "What our customers say"
msgstr ""
-#: alplora/templates/alplora/index.html:379
msgid ""
"“Alplora is an innovation in looking after my cows. I can check where my "
"cows have been in the higher mountain all day while doing other works at the "
@@ -292,11 +230,9 @@ msgstr ""
"selben Zeit andereDinge auf dem Hof unten im Dorf erledigen. Dank Alplora "
"kann ich meinen Kühenmehr Sicherheit gewährleisten."
-#: alplora/templates/alplora/index.html:382
msgid "Farmer in canton Glarus"
msgstr "Bauern im Kanton Glarus"
-#: alplora/templates/alplora/index.html:388
msgid ""
"\"Alplora is exactly what I was waiting for. I have lost my sheep almost "
"every year. Finally I have a way when I want to locate them.\""
@@ -305,11 +241,9 @@ msgstr ""
"Schafe fastjedes Jahr aus den Augen verloren. Nun habe ich endlich die "
"Möglichkeit, sie zulokalisieren.\""
-#: alplora/templates/alplora/index.html:391
msgid "Owner of 50 sheep "
msgstr "Besitzerin von 50 Schafen"
-#: alplora/templates/alplora/index.html:397
msgid ""
"\"I have a farm down all the way down in the village and y goats are always "
"freely grazing in the Alps. There are times that I am worried about them but "
@@ -323,30 +257,23 @@ msgstr ""
"noch um meineanderen Tiere kümmern muss. Mit Alplora kann ich nun ohne "
"Probleme beides tun.\""
-#: alplora/templates/alplora/index.html:401
msgid "Farmer at Berner Oberland"
msgstr "Bauer aus dem Berner Oberland"
-#: alplora/templates/alplora/index.html:418
msgid "How do I get Alplora?"
msgstr "Wie kriege ich Zugriff zu Alplora?"
-#: alplora/templates/alplora/index.html:419
msgid "Click the button below and leave us your contact."
msgstr "Klicke unten auf Kontakt und hinterlasse uns deine Angaben."
-#: alplora/templates/alplora/index.html:419
msgid "Team Alplora will contact you and visit you with a tracking device."
msgstr "Das Alpora Team wird sich mit Dir schnellstens in Verbindung setzen."
-#: alplora/templates/alplora/index.html:459
msgid "Home"
msgstr "Startseite"
-#: alplora/templates/alplora/index.html:472
msgid "Testimonials "
msgstr "Referenzen"
-#: alplora/views.py:24
msgid "Message Successfully Sent"
msgstr ""
diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po
index 3c7869a1..c69f83d1 100644
--- a/datacenterlight/locale/de/LC_MESSAGES/django.po
+++ b/datacenterlight/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-09-16 14:09+0000\n"
+"POT-Creation-Date: 2017-11-13 17:59+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -65,24 +65,6 @@ msgstr "Bitte gib einen Wert von 10 bis 200 ein."
msgid "GB Storage (SSD)"
msgstr "GB Storage (SSD)"
-msgid "Name"
-msgstr ""
-
-msgid "Your Name"
-msgstr "Dein Name"
-
-msgid "Please enter your name."
-msgstr "Bitte gib Deinen Namen ein."
-
-msgid "Email"
-msgstr "E-Mail-Adresse"
-
-msgid "Your Email"
-msgstr "Deine E-Mail"
-
-msgid "Please enter a valid email address."
-msgstr "Bitte gib eine gültige E-Mailadresse ein."
-
msgid "Continue"
msgstr "Weiter"
@@ -95,6 +77,18 @@ msgstr "Vielen Dank für Deine Nachricht."
msgid "Get in touch with us!"
msgstr "Sende uns eine Nachricht."
+msgid "Name"
+msgstr ""
+
+msgid "Please enter your name."
+msgstr "Bitte gib Deinen Namen ein."
+
+msgid "Email"
+msgstr "E-Mail-Adresse"
+
+msgid "Please enter a valid email address."
+msgstr "Bitte gib eine gültige E-Mailadresse ein."
+
msgid "Message"
msgstr "Nachricht"
@@ -132,36 +126,57 @@ msgstr ""
msgid "Thank you!"
msgstr "Vielen Dank!"
-msgid "Account Activation"
-msgstr "Account Aktivierung"
+msgid "Data Center Light Account Activation"
+msgstr "Data Center Light Account Aktivierung"
#, python-format
msgid ""
-"\n"
-"You can activate your Data Center Light account by clicking here. \n"
-"You can also copy and paste the following link into the address bar of your "
-"browser \n"
-"to activate your Data Center Light account. \n"
-"%(base_url)s%(activation_link)s\n"
+"You can activate your Data Center Light account by clicking here."
msgstr ""
-"\n"
-"Klicke hier um deinen Data "
-"Center Light Account zu aktivieren oder kopiere den folgenden Link in die "
-"Adressleiste deines Browsers. \n"
-"%(base_url)s%(activation_link)s\n"
+"Klicke here um deinen Data Center "
+"Light Account zu aktivieren."
-#, python-format
msgid ""
-"You can activate your Data Center Light account by clicking here.\n"
"You can also copy and paste the following link into the address bar of your "
-"browser\n"
-"to activate your Data Center Light account.\n"
-"%(base_url)s%(activation_link)s\n"
-msgstr ""
-"Klicke hier, um deinen Data Center Light Account zu aktivieren oder kopiere "
-"den folgenden Link in die Adressleiste deines Browsers.\n"
-"%(base_url)s%(activation_link)s\n"
+"browser to activate your Data Center Light account."
+msgstr "Kopiere den folgenden Link in die Adressleiste deines Browsers."
+
+msgid "Your account details are as follows"
+msgstr "Deine Account Details sind unten aufgelistet"
+
+msgid "Username"
+msgstr "Username"
+
+msgid "Your email address"
+msgstr "Deine E-Mail-Adresse"
+
+msgid "Password"
+msgstr "Passwort"
+
+msgid "You can reset your password here"
+msgstr "Du kannst dein Passwort hier zurück setzen"
+
+msgid ""
+"You can copy and paste the following link into the address bar of your "
+"browser to activate your Data Center Light account."
+msgstr "Kopiere den folgenden Link in die Adressleiste deines Browsers."
+
+msgid "Welcome to Data Center Light!"
+msgstr "Willkommen beim Data Center Light!"
+
+msgid ""
+"Thanks for joining us! We provide the most affordable virtual machines from "
+"the heart of Switzerland."
+msgstr "Bei uns findest Du die günstiges VMs aus der Schweiz."
+
+msgid "Try now, order a VM. VM price starts from only 15CHF per month."
+msgstr "Unser Angebot beginnt bei 15 CHF pro Monat. Probier's jetzt aus!"
+
+msgid "ORDER VM"
+msgstr "VM BESTELLEN"
msgid "Home"
msgstr "Home"
@@ -255,8 +270,12 @@ msgstr ""
"Einfach und bezahlbar: Teste nun unsere virtuellen Maschinen mit "
"federleichten Preisen."
-msgid "Affordable VM hosting based in Switzerland"
-msgstr "Bezahlbares VM Hosting in der Schweiz"
+msgid ""
+"Ready in 30 seconds. Experience the unbeatable speed from Data Center "
+"Light."
+msgstr ""
+"Fertig in 30 Sekunden. Erlebe die unschlagbare Geschwindigkeit von Data "
+"Center Light."
msgid "Contact us"
msgstr "Kontaktiere uns"
@@ -264,6 +283,45 @@ msgstr "Kontaktiere uns"
msgid "Switzerland "
msgstr "Schweiz "
+msgid "Welcome back"
+msgstr "Willkommen zurück"
+
+msgid ""
+"Review your billing address and card details and proceed to make payment."
+msgstr ""
+"Überprüfe die Rechnungsadresse und Kreditkartendaten und fahre mit der "
+"Zahlung fort."
+
+msgid "Log in"
+msgstr "Anmelden"
+
+msgid ""
+"Already signed up? By logging in you can retrieve saved billing "
+"information."
+msgstr ""
+"Bereits eingeloggt? Nach der Anmeldung kannst Du gespeicherte "
+"Rechnungsinformationen abrufen."
+
+msgid "LOGIN"
+msgstr "ANMELDEN"
+
+msgid "Don't have an account yet?"
+msgstr "Besitzt du kein Benutzerkonto?"
+
+msgid "You can sign up by filling in the information below."
+msgstr ""
+"Du kannst Dich anmelden, indem Du die die untenstehenden Informationen "
+"ausfüllst."
+
+msgid "Forgot password?"
+msgstr "Passwort vergessen?"
+
+msgid "Sign up"
+msgstr "Registrieren"
+
+msgid "Billing Address"
+msgstr "Rechnungsadresse"
+
msgid "Your Order"
msgstr "Deine Bestellung"
@@ -288,23 +346,15 @@ msgstr "inkl. Mehrwertsteuer"
msgid "Month"
msgstr "Monat"
-msgid "Billing Address"
-msgstr "Rechnungsadresse"
-
msgid "Credit Card"
msgstr "Kreditkarte"
msgid ""
-"\n"
-" Please fill in your credit card information "
-"below. We are using Stripe for payment and do not store\n"
-" your information in our database.\n"
-" "
+"Please fill in your credit card information below. We are using Stripe for payment and do not "
+"store your information in our database."
msgstr ""
-"\n"
-"Bitte füll Deine Kreditkarteninformationen unten aus. Wir nutzen Stripe für die Bezahlung und "
"speichern keine Informationen in unserer Datenbank."
@@ -315,9 +365,6 @@ msgstr ""
"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, "
"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast."
-msgid "Submit"
-msgstr "Absenden"
-
msgid "Card Number"
msgstr "Kreditkartennummer"
@@ -330,30 +377,19 @@ msgstr ""
msgid "Card Type"
msgstr "Kartentyp"
+msgid ""
+"You are not making any payment yet. After placing your order, you will be "
+"taken to the Submit Payment Page."
+msgstr ""
+"Es wird noch keine Bezahlung vorgenommen. Die Bezahlung wird erst ausgelöst, "
+"nachdem Du die Bestellung auf der nächsten Seite bestätigt hast."
+
msgid "Processing"
msgstr "Weiter"
msgid "Enter your credit card number"
msgstr "Deine Kreditkartennummer"
-msgid "Confirm Order"
-msgstr "Bestellung Bestätigen"
-
-msgid "Date"
-msgstr "Datum"
-
-msgid "Billed To:"
-msgstr "Rechnungsadresse"
-
-msgid "Payment Method:"
-msgstr "Bezahlmethode"
-
-msgid "ending in"
-msgstr "endend in"
-
-msgid "Order summary"
-msgstr "Bestellungsübersicht"
-
#, python-format
msgid ""
"By clicking \"Place order\" this plan will charge your credit card account "
@@ -365,27 +401,6 @@ msgstr ""
msgid "Place order"
msgstr "Bestellen"
-msgid "We are cutting down the costs significantly!"
-msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen"
-
-msgid "Order Now!"
-msgstr "Bestelle jetzt!"
-
-msgid ""
-"Our VMs are hosted in Glarus, Switzerland, and our website is currently "
-"running in BETA mode. If you want more information that you did not find on "
-"our website, or if your order is more detailed, or if you encounter any "
-"technical hiccups, please contact us at support@datacenterlight.ch, our team "
-"will get in touch with you asap."
-msgstr ""
-"Unsere VMs werden in der Schweiz im Kanton Glarus gehostet und befinden sich "
-"zur Zeit noch in der BETA-Phase. Möchtest du mehr über uns erfahren und hast "
-"auf unserer Website nicht genügend Informationen gefunden? Möchtest eine "
-"detailliertere Bestellung aufgeben? Bist du auf technische Probleme "
-"gestossen, die du uns mitteilen möchtest? Dann zögere nicht und kontaktiere "
-"uns unter support@datacenterlight.ch. Unser Team wird sich umgehend um dein "
-"Anliegen kümmern!"
-
msgid "Thank you for order! Our team will contact you via email"
msgstr ""
"Vielen Dank für die Bestellung. Unser Team setzt sich sobald wie möglich mit "
@@ -479,11 +494,91 @@ msgstr "Ungültige RAM-Grösse"
msgid "Invalid storage size"
msgstr "Ungültige Speicher-Grösse"
-msgid "is not a proper name"
-msgstr "ist kein gültiger Name"
+msgid "Confirm Order"
+msgstr "Bestellung Bestätigen"
-msgid "is not a proper email"
-msgstr "ist keine gültige E-Mailadresse"
+msgid "Error."
+msgstr ""
+
+msgid ""
+"There was a payment related error. On close of this popup, you will be "
+"redirected back to the payment page."
+msgstr ""
+"Es ist ein Fehler bei der Zahlung betreten. Du wirst nach dem Schliessen vom "
+"Popup zur Bezahlseite weitergeleitet."
+
+msgid "Thank you for the order."
+msgstr "Danke für Deine Bestellung."
+
+msgid ""
+"Your VM will be up and running in a few moments. We will send you a "
+"confirmation email as soon as it is ready."
+msgstr ""
+"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
+"auf sie zugreifen kannst."
+
+#~ msgid "Affordable VM hosting based in Switzerland"
+#~ msgstr "Bezahlbares VM Hosting in der Schweiz"
+
+#~ msgid "Processing..."
+#~ msgstr "Abarbeitung..."
+
+#~ msgid "Hold tight, we are processing your request"
+#~ msgstr "Bitte warten - wir verbeiten Deine Anfrage gerade"
+
+#~ msgid "Some problem encountered. Please try again later."
+#~ msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
+
+#~ msgid "Submit"
+#~ msgstr "Absenden"
+
+#~ msgid "Date"
+#~ msgstr "Datum"
+
+#~ msgid "Billed To:"
+#~ msgstr "Rechnungsadresse"
+
+#~ msgid "Payment Method:"
+#~ msgstr "Bezahlmethode"
+
+#~ msgid "ending in"
+#~ msgstr "endend in"
+
+#~ msgid "Order summary"
+#~ msgstr "Bestellungsübersicht"
+
+#~ msgid "We are cutting down the costs significantly!"
+#~ msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen"
+
+#~ msgid "Order Now!"
+#~ msgstr "Bestelle jetzt!"
+
+#~ msgid ""
+#~ "Our VMs are hosted in Glarus, Switzerland, and our website is currently "
+#~ "running in BETA mode. If you want more information that you did not find "
+#~ "on our website, or if your order is more detailed, or if you encounter "
+#~ "any technical hiccups, please contact us at support@datacenterlight.ch, "
+#~ "our team will get in touch with you asap."
+#~ msgstr ""
+#~ "Unsere VMs werden in der Schweiz im Kanton Glarus gehostet und befinden "
+#~ "sich zur Zeit noch in der BETA-Phase. Möchtest du mehr über uns erfahren "
+#~ "und hast auf unserer Website nicht genügend Informationen gefunden? "
+#~ "Möchtest eine detailliertere Bestellung aufgeben? Bist du auf technische "
+#~ "Probleme gestossen, die du uns mitteilen möchtest? Dann zögere nicht und "
+#~ "kontaktiere uns unter support@datacenterlight.ch. Unser Team wird sich "
+#~ "umgehend um dein Anliegen kümmern!"
+
+#~ msgid "is not a proper name"
+#~ msgstr "ist kein gültiger Name"
+
+#~ msgid "is not a proper email"
+#~ msgstr "ist keine gültige E-Mailadresse"
+
+#~ msgid "Your Name"
+#~ msgstr "Dein Name"
+
+#~ msgid "Your Email"
+#~ msgstr "Deine E-Mail"
#~ msgid ""
#~ "\n"
diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css
index d50a864d..9b02420c 100755
--- a/datacenterlight/static/datacenterlight/css/landing-page.css
+++ b/datacenterlight/static/datacenterlight/css/landing-page.css
@@ -182,7 +182,11 @@ button, input, optgroup, select, textarea {
.navbar-brand {
padding: 10px 15px;
- cursor: pointer;
+}
+@media (max-width: 767px) {
+ .navbar-brand {
+ padding: 10px 10px;
+ }
}
.navbar-right {
@@ -276,7 +280,7 @@ button, input, optgroup, select, textarea {
display: block;
} */
.intro-header {
- height: 100vh;
+ min-height: 100vh;
text-align: center;
color: #fff;
background: url(../img/configure.jpg) no-repeat center center;
@@ -715,9 +719,10 @@ button, input, optgroup, select, textarea {
font-size: 65px;
margin: 0;
position: relative;
-/* color: #eee;
+ /* color: #eee;
padding-bottom: 25px;
text-align: right; */
+ /* color: #fff; */
}
.contact-form .form-group {
@@ -1501,6 +1506,8 @@ tech-sub-sec h2 {
font-size: 14px;
font-weight: 300;
letter-spacing: 2px;
+ line-height: 24px;
+ display: block;
}
.content-section-a {
@@ -1541,7 +1548,7 @@ tech-sub-sec h2 {
}
footer {
- padding: 50px 0;
+ padding: 50px 20px;
background-color: #f8f8f8;
}
diff --git a/datacenterlight/static/datacenterlight/img/logo_black.png b/datacenterlight/static/datacenterlight/img/logo_black.png
new file mode 100644
index 00000000..5dfd0eaa
Binary files /dev/null and b/datacenterlight/static/datacenterlight/img/logo_black.png differ
diff --git a/datacenterlight/static/datacenterlight/img/pattern.jpg b/datacenterlight/static/datacenterlight/img/pattern.jpg
index 8ae4c0f2..7c66e007 100755
Binary files a/datacenterlight/static/datacenterlight/img/pattern.jpg and b/datacenterlight/static/datacenterlight/img/pattern.jpg differ
diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js
index ab37a68b..dd074397 100644
--- a/datacenterlight/static/datacenterlight/js/main.js
+++ b/datacenterlight/static/datacenterlight/js/main.js
@@ -155,9 +155,7 @@
function _calcPricing() {
var total = (cardPricing['cpu'].value * 5) + (2 * cardPricing['ram'].value) + (0.6 * cardPricing['storage'].value);
total = parseFloat(total.toFixed(2));
-
$("#total").text(total);
- $('input[name=total]').val(total);
}
function form_success() {
@@ -191,4 +189,4 @@
});
})
}
-})(jQuery);
\ No newline at end of file
+})(jQuery);
diff --git a/datacenterlight/tasks.py b/datacenterlight/tasks.py
index 1335869b..3db6eb54 100644
--- a/datacenterlight/tasks.py
+++ b/datacenterlight/tasks.py
@@ -5,6 +5,7 @@ from celery.utils.log import get_task_logger
from celery import current_task
from django.conf import settings
from django.core.mail import EmailMessage
+from django.core.urlresolvers import reverse
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
@@ -13,7 +14,7 @@ from hosting.models import HostingOrder, HostingBill
from membership.models import StripeCustomer, CustomUser
from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineSerializer
-from utils.hosting_utils import get_all_public_keys
+from utils.hosting_utils import get_all_public_keys, get_or_create_vm_detail
from utils.forms import UserBillingAddressForm
from utils.mailer import BaseEmail
from utils.models import BillingAddress
@@ -50,14 +51,20 @@ def retry_task(task, exception=None):
@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
def create_vm_task(self, vm_template_id, user, specs, template,
stripe_customer_id, billing_address_data,
- billing_address_id,
- charge, cc_details):
- logger.debug("Running create_vm_task on {}".format(current_task.request.hostname))
+ stripe_subscription_id, cc_details):
+ logger.debug(
+ "Running create_vm_task on {}".format(current_task.request.hostname))
vm_id = None
try:
final_price = specs.get('price')
- billing_address = BillingAddress.objects.filter(
- id=billing_address_id).first()
+ billing_address = BillingAddress(
+ cardholder_name=billing_address_data['cardholder_name'],
+ street_address=billing_address_data['street_address'],
+ city=billing_address_data['city'],
+ postal_code=billing_address_data['postal_code'],
+ country=billing_address_data['country']
+ )
+ billing_address.save()
customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
if 'pass' in user:
@@ -110,8 +117,7 @@ def create_vm_task(self, vm_template_id, user, specs, template,
billing_address_user_form.save()
# Associate an order with a stripe subscription
- charge_object = DictDotLookup(charge)
- order.set_subscription_id(charge_object, cc_details)
+ order.set_subscription_id(stripe_subscription_id, cc_details)
# If the Stripe payment succeeds, set order status approved
order.set_approved()
@@ -126,9 +132,9 @@ def create_vm_task(self, vm_template_id, user, specs, template,
'storage': specs.get('disk_size'),
'price': specs.get('price'),
'template': template.get('name'),
- 'vm.name': vm['name'],
- 'vm.id': vm['vm_id'],
- 'order.id': order.id
+ 'vm_name': vm.get('name'),
+ 'vm_id': vm['vm_id'],
+ 'order_id': order.id
}
email_data = {
'subject': settings.DCL_TEXT + " Order from %s" % context['email'],
@@ -142,20 +148,22 @@ def create_vm_task(self, vm_template_id, user, specs, template,
email.send()
if 'pass' in user:
- lang = 'en-us'
+ lang = 'en-us'
if user.get('language') is not None:
- logger.debug("Language is set to {}".format(user.get('language')))
+ logger.debug(
+ "Language is set to {}".format(user.get('language')))
lang = user.get('language')
translation.activate(lang)
# Send notification to the user as soon as VM has been booked
context = {
- 'vm': vm,
- 'order': order,
'base_url': "{0}://{1}".format(user.get('request_scheme'),
user.get('request_host')),
+ 'order_url': reverse('hosting:orders',
+ kwargs={'pk': order.id}),
'page_header': _(
'Your New VM %(vm_name)s at Data Center Light') % {
- 'vm_name': vm.get('name')}
+ 'vm_name': vm.get('name')},
+ 'vm_name': vm.get('name')
}
email_data = {
'subject': context.get('page_header'),
@@ -174,13 +182,15 @@ def create_vm_task(self, vm_template_id, user, specs, template,
logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id))
if new_host is not None:
custom_user = CustomUser.objects.get(email=user.get('email'))
+ get_or_create_vm_detail(custom_user, manager, vm_id)
if custom_user is not None:
public_keys = get_all_public_keys(custom_user)
keys = [{'value': key, 'state': True} for key in
public_keys]
if len(keys) > 0:
logger.debug(
- "Calling configure on {host} for {num_keys} keys".format(
+ "Calling configure on {host} for "
+ "{num_keys} keys".format(
host=new_host, num_keys=len(keys)))
# Let's delay the task by 75 seconds to be sure
# that we run the cdist configure after the host
@@ -209,32 +219,3 @@ def create_vm_task(self, vm_template_id, user, specs, template,
return
return vm_id
-
-
-class DictDotLookup(object):
- """
- Creates objects that behave much like a dictionaries, but allow nested
- key access using object '.' (dot) lookups.
- """
-
- def __init__(self, d):
- for k in d:
- if isinstance(d[k], dict):
- self.__dict__[k] = DictDotLookup(d[k])
- elif isinstance(d[k], (list, tuple)):
- l = []
- for v in d[k]:
- if isinstance(v, dict):
- l.append(DictDotLookup(v))
- else:
- l.append(v)
- self.__dict__[k] = l
- else:
- self.__dict__[k] = d[k]
-
- def __getitem__(self, name):
- if name in self.__dict__:
- return self.__dict__[name]
-
- def __iter__(self):
- return iter(self.__dict__.keys())
diff --git a/datacenterlight/templates/datacenterlight/base.html b/datacenterlight/templates/datacenterlight/base.html
index 45b30cad..58e6b15a 100644
--- a/datacenterlight/templates/datacenterlight/base.html
+++ b/datacenterlight/templates/datacenterlight/base.html
@@ -18,7 +18,7 @@
-
+
@@ -26,6 +26,8 @@
+ {% block css_extra %}
+ {% endblock css_extra %}
@@ -42,7 +44,9 @@
- {% include "datacenterlight/includes/_navbar.html" %}
+ {% block navbar %}
+ {% include "datacenterlight/includes/_navbar.html" %}
+ {% endblock navbar %}
{% block content %}
diff --git a/datacenterlight/templates/datacenterlight/calculator_form.html b/datacenterlight/templates/datacenterlight/calculator_form.html
index b5bac1f9..1733a719 100644
--- a/datacenterlight/templates/datacenterlight/calculator_form.html
+++ b/datacenterlight/templates/datacenterlight/calculator_form.html
@@ -77,47 +77,9 @@
{% endfor %}
-
-
-
-
-
-
-
- {% for message in messages %}
- {% if 'name' in message.tags %}
-
-
- {{ message|safe }}
-
-
- {% endif %}
- {% endfor %}
-
-
-
-
-
-
-
-
- {% for message in messages %}
- {% if 'email' in message.tags %}
-
-
- {{ message|safe }}
-
-
- {% endif %}
- {% endfor %}
-
-
diff --git a/datacenterlight/templates/datacenterlight/emails/user_activation.html b/datacenterlight/templates/datacenterlight/emails/user_activation.html
index 955eed18..8f270a3f 100644
--- a/datacenterlight/templates/datacenterlight/emails/user_activation.html
+++ b/datacenterlight/templates/datacenterlight/emails/user_activation.html
@@ -1,14 +1,58 @@
-{% extends "datacenterlight/emails/base_email_datacenterlight.html" %}
-{% load static from staticfiles %}
-{% load i18n %}
-{% block email_head %}
-{{dcl_text}} {% trans 'Account Activation' %}
-{% endblock %}
-{% block email_body %}
-{% blocktrans %}
-You can activate your Data Center Light account by clicking here.
-You can also copy and paste the following link into the address bar of your browser
-to activate your Data Center Light account.
-{{base_url}}{{activation_link}}
-{% endblocktrans %}
-{% endblock %}
+{% load static i18n %}
+
+
+
+
+
+
+ {% trans "Data Center Light Account Activation" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Data Center Light Account Activation" %}
+
+
+
+
+
+ {% blocktrans %}You can activate your Data Center Light account by clicking here.{% endblocktrans %}
+
+
+ {% blocktrans %}You can also copy and paste the following link into the address bar of your browser to activate your Data Center Light account.{% endblocktrans %}
+
+
+ {{base_url}}{{activation_link}}
+
+
+ {% if account_details %}
+ {% url 'hosting:reset_password' as reset_password_url %}
+ {% trans "Your account details are as follows" %}:
+
+ {% trans "Username" %} : {% trans "Your email address" %}
+ {% trans "Password" %} : {{account_details}}
+
+ {% trans "You can reset your password here" %}:
+ {{base_url}}{{reset_password_url}}
+ {% endif %}
+
+
+
+
+
+
{% trans "Your Data Center Light Team" %}
+
+
+
+
+
+
diff --git a/datacenterlight/templates/datacenterlight/emails/user_activation.txt b/datacenterlight/templates/datacenterlight/emails/user_activation.txt
index 84ec50a9..4f66e239 100644
--- a/datacenterlight/templates/datacenterlight/emails/user_activation.txt
+++ b/datacenterlight/templates/datacenterlight/emails/user_activation.txt
@@ -1,10 +1,20 @@
-{% extends "datacenterlight/emails/base_email_datacenterlight.txt" %}
{% load i18n %}
-{% block email_head %}{{dcl_text}} {% trans 'Account Activation' %}{% endblock %}
-{% block email_body %}
-{% blocktrans %}You can activate your Data Center Light account by clicking here.
-You can also copy and paste the following link into the address bar of your browser
-to activate your Data Center Light account.
+
+{% trans "Data Center Light Account Activation" %}
+
+{% blocktrans %}You can copy and paste the following link into the address bar of your browser to activate your Data Center Light account.{% endblocktrans %}
+
{{base_url}}{{activation_link}}
-{% endblocktrans %}
-{% endblock %}
+
+{% if account_details %}
+ {% url 'hosting:reset_password' as reset_password_url %}
+ {% trans "Your account details are as follows" %}:
+
+ {% trans "Username" %} : {% trans "Your email address" %}
+ {% trans "Password" %} : {{account_details}}
+
+ {% trans "You can reset your password here" %}:
+ {{base_url}}{{reset_password_url}}
+{% endif %}
+
+{% trans "Your Data Center Light Team" %}
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/emails/welcome_user.html b/datacenterlight/templates/datacenterlight/emails/welcome_user.html
new file mode 100644
index 00000000..e947ac97
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/emails/welcome_user.html
@@ -0,0 +1,48 @@
+{% load static i18n %}
+
+
+
+
+
+
+ {% trans "Welcome to Data Center Light!" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Welcome to Data Center Light!" %}
+
+
+
+
+
+ {% blocktrans %}Thanks for joining us! We provide the most affordable virtual machines from the heart of Switzerland.{% endblocktrans %}
+
+
+ {% blocktrans %}Try now, order a VM. VM price starts from only 15CHF per month.{% endblocktrans %}
+
+
+
+
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/emails/welcome_user.txt b/datacenterlight/templates/datacenterlight/emails/welcome_user.txt
new file mode 100644
index 00000000..0e7820e6
--- /dev/null
+++ b/datacenterlight/templates/datacenterlight/emails/welcome_user.txt
@@ -0,0 +1,10 @@
+{% load i18n %}
+
+{% trans "Welcome to Data Center Light!" %}
+
+{% blocktrans %}Thanks for joining us! We provide the most affordable virtual machines from the heart of Switzerland.{% endblocktrans %}
+{% blocktrans %}Try now, order a VM. VM price starts from only 15CHF per month.{% endblocktrans %}
+
+{{ base_url }}{% url 'hosting:create_virtual_machine' %}
+
+{% trans "Your Data Center Light Team" %}
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/includes/_footer.html b/datacenterlight/templates/datacenterlight/includes/_footer.html
index 76c2c16e..edb7f8aa 100644
--- a/datacenterlight/templates/datacenterlight/includes/_footer.html
+++ b/datacenterlight/templates/datacenterlight/includes/_footer.html
@@ -1,38 +1,39 @@
- {% load staticfiles i18n%}
+{% load staticfiles i18n%}
{% get_current_language as LANGUAGE_CODE %}
-
+
diff --git a/datacenterlight/templates/datacenterlight/index.html b/datacenterlight/templates/datacenterlight/index.html
index cde420dd..cc3597ec 100755
--- a/datacenterlight/templates/datacenterlight/index.html
+++ b/datacenterlight/templates/datacenterlight/index.html
@@ -16,7 +16,7 @@
+ {% blocktrans %}Please fill in your credit card information below. We are using Stripe for payment and do not store your information in our database.{% endblocktrans %}
+
-
-
- {% blocktrans %}
- Please fill in your credit card information below. We are using Stripe for payment and do not store
- your information in our database.
- {% endblocktrans %}
-
-
-
-
- {% if credit_card_data.last4 %}
+ {% if credit_card_data.last4 %}
-
-
- {% if not messages and not form.non_field_errors %}
-
- {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %}
-
- {% endif %}
-
- {% for message in messages %}
- {% if 'failed_payment' or 'make_charge_error' in message.tags %}
-
-
{{ message|safe }}
-
- {% endif %}
- {% endfor %}
- {% for error in form.non_field_errors %}
-
- {{ error|escape }}
-
- {% endfor %}
-
-
-
-
-
-
-
+ {% if not messages and not form.non_field_errors %}
+
+ {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %}
+
+ {% endif %}
+
+ {% for message in messages %}
+ {% if 'failed_payment' or 'make_charge_error' in message.tags %}
+
+
+
{{ message|safe }}
+
+
+ {% endif %}
+ {% endfor %}
+ {% for error in form.non_field_errors %}
+