Hallo now edits my images,

and each post can display a dedicated photo.

* NpgsqlBlogProvider.cs: implements a blog post photo storage

* BlogsController.cs: implements a method to update the photo url

* style.css: yastyle

* AdminController.cs: refactoring the notification:
Introduces a static `Notice` method, server side, to populate an array
in `ViewData`, used in the paster page.

* BlogsController.cs: Controls the photo update

* YavscHelpers.cs:
* yavsc.circles.js:
* HomeController.cs:
* GoogleController.cs: notification refactoring

* App.master: - notification refactoring
- html structure in the `nav`

* hallo.js: event 'hallomodified' now also occurs at image
  modifications

* to-markdown.js: ?Fixes? html images alt text and title to Markdown

* yavsc.js: implements the photo in database

* Edit.aspx: A nicer bill edition, with a photo

* UserPost.aspx: Displays the photo

* UserPosts.aspx: Fixes the new usage of `ResultPages`

* Web.config: totem custo

* instdbws.sql: adds a `photo` field in the `blog` table

* BlogEntry.cs: defines the photo in the model

* BlogManager.cs: a new method to set the photo on a blog post.

* BlogProvider.cs: the blog provider now also gives some photo

* LocalizedText.fr.Designer.cs: Reordering the french localisation
  resource

* LocalizedText.fr.resx: Reorders the french localisation resource
main
Paul Schneider 10 years ago
parent 303e4fa57b
commit 9494d6f353
26 changed files with 1015 additions and 828 deletions

@ -0,0 +1,4 @@
2015-10-08 Paul Schneider <paul@pschneider.fr>
* NpgsqlBlogProvider.cs: implements a blog post photo storage

@ -236,7 +236,7 @@ namespace Npgsql.Web.Blog
BlogEntry be = null; BlogEntry be = null;
using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString))
using (NpgsqlCommand cmd = cnx.CreateCommand()) { using (NpgsqlCommand cmd = cnx.CreateCommand()) {
cmd.CommandText = "select username, title, bcontent, modified, posted, visible from blog " + cmd.CommandText = "select username, title, bcontent, modified, posted, visible, photo from blog " +
"where applicationname = @appname and _id = @id"; "where applicationname = @appname and _id = @id";
cmd.Parameters.AddWithValue ("@appname", applicationName); cmd.Parameters.AddWithValue ("@appname", applicationName);
cmd.Parameters.AddWithValue ("@id", postid); cmd.Parameters.AddWithValue ("@id", postid);
@ -250,6 +250,7 @@ namespace Npgsql.Web.Blog
be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified"));
be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted"));
be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible"));
be.Photo = rdr.GetString (rdr.GetOrdinal ("photo"));
be.Id = postid; be.Id = postid;
} }
} }
@ -285,7 +286,7 @@ namespace Npgsql.Web.Blog
UUTBlogEntryCollection bec = new UUTBlogEntryCollection (username,title); UUTBlogEntryCollection bec = new UUTBlogEntryCollection (username,title);
using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) {
using (NpgsqlCommand cmd = cnx.CreateCommand ()) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "select _id,bcontent,modified,posted,visible from blog " + cmd.CommandText = "select _id,bcontent,modified,posted,visible,photo from blog " +
"where applicationname = :appname and username = :username and title = :title"; "where applicationname = :appname and username = :username and title = :title";
cmd.Parameters.AddWithValue ("appname", NpgsqlDbType.Varchar, applicationName); cmd.Parameters.AddWithValue ("appname", NpgsqlDbType.Varchar, applicationName);
cmd.Parameters.AddWithValue ("username", NpgsqlDbType.Varchar ,username); cmd.Parameters.AddWithValue ("username", NpgsqlDbType.Varchar ,username);
@ -302,6 +303,7 @@ namespace Npgsql.Web.Blog
be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted"));
be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible"));
be.Id = rdr.GetInt64 (rdr.GetOrdinal ("_id")); be.Id = rdr.GetInt64 (rdr.GetOrdinal ("_id"));
be.Photo = rdr.GetString (rdr.GetOrdinal ("photo"));
bec.Add (be); bec.Add (be);
} }
rdr.Close (); rdr.Close ();
@ -393,6 +395,24 @@ namespace Npgsql.Web.Blog
UpdatePostCircles (pid, circles); UpdatePostCircles (pid, circles);
return pid; return pid;
} }
/// <summary>
/// Updates the post photo.
/// </summary>
/// <param name="pid">Pid.</param>
/// <param name="photo">Photo.</param>
public override void UpdatePostPhoto ( long pid, string photo)
{
using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) {
cnx.Open ();
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "update blog set photo = :photo where _id = :pid";
cmd.Parameters.AddWithValue ("pid", pid);
cmd.Parameters.AddWithValue ("photo", photo);
cmd.ExecuteNonQuery ();
}
cnx.Close ();
}
}
private void UpdatePostCircles( long pid, long[] circles) private void UpdatePostCircles( long pid, long[] circles)
{ {

@ -125,10 +125,29 @@ namespace Yavsc.ApiControllers
} }
} }
/// <summary>
/// Searchs the files accociated to the given post id,
/// or related to the given terms.
/// </summary>
/// <returns>The file.</returns>
/// <param name="postid">Postid.</param>
/// <param name="terms">Terms.</param>
[Authorize,HttpGet] [Authorize,HttpGet]
public async Task<HttpResponseMessage> SearchFile(long postid, string terms) { public async Task<HttpResponseMessage> SearchFile(long postid, string terms) {
throw new NotImplementedException (); throw new NotImplementedException ();
} }
/// <summary>
/// Sets the photo.
/// </summary>
/// <param name="id">Identifier.</param>
/// <param name="photo">Photo.</param>
[Authorize,HttpPost]
public void SetPhoto(long id, string photo)
{
BlogManager.Provider.UpdatePostPhoto (id, photo);
}
/// <summary> /// <summary>
/// Import the specified id. /// Import the specified id.
/// </summary> /// </summary>
@ -138,7 +157,7 @@ namespace Yavsc.ApiControllers
throw new HttpRequestException ("not a multipart/form-data request"); throw new HttpRequestException ("not a multipart/form-data request");
BlogEntry be = BlogManager.GetPost (id); BlogEntry be = BlogManager.GetPost (id);
if (be.Author != Membership.GetUser ().UserName) if (be.Author != Membership.GetUser ().UserName)
throw new AuthorizationDenied ("b"+id); throw new AuthorizationDenied ("post: "+id);
string root = HttpContext.Current.Server.MapPath("~/bfiles/"+id); string root = HttpContext.Current.Server.MapPath("~/bfiles/"+id);
DirectoryInfo di = new DirectoryInfo (root); DirectoryInfo di = new DirectoryInfo (root);
if (!di.Exists) di.Create (); if (!di.Exists) di.Create ();

@ -75,7 +75,7 @@ a.actionlink img, h1 img, .menuitem img { vertical-align: middle; }
border-radius:5px; border-radius:5px;
margin:.5em; padding:1em; display: inline-block } margin:.5em; padding:1em; display: inline-block }
fieldset { fieldset {
background-color: rgba(32,16,16,0.8); background-color: rgba(16,16,64,0.8);
border-radius:5px; border: solid 1px #000060; border-radius:5px; border: solid 1px #000060;
} }
@ -96,7 +96,7 @@ aside {
max-width: 40em; max-width: 40em;
padding: .5em; padding: .5em;
margin: .5em; margin: .5em;
background-color: rgba(32,32,32,0.8); background-color: rgba(0,0,32,0.8);
border-radius:10px; border-radius:10px;
} }
.postpreview video, .postpreview img { .postpreview video, .postpreview img {
@ -107,7 +107,7 @@ aside {
display:block; display:block;
margin:1em; margin:1em;
padding:1em; padding:1em;
background-color: rgba(32,32,32,0.8); background-color: rgba(0,0,32,0.8);
color: #aaa; color: #aaa;
border-radius:10px; border-radius:10px;
} }
@ -125,7 +125,7 @@ textarea.fullwidth { min-height:10em; }
} }
.panel,.bshpanel, aside { .panel,.bshpanel, aside {
background-color: rgba(32,32,16,0.8); background-color: rgba(0,0,128,.5);
border-radius:5px; border-radius:5px;
margin:.5em; margin:.5em;
padding: .5em; padding: .5em;
@ -167,9 +167,14 @@ label {
font-size: medium; font-size: medium;
} }
.message, #message { #notifications {
padding: .5em;
}
.notification {
font-size: large; font-size: large;
background-color: rgba(64,64,0,0.5); background-color: rgba(64,64,0,0.5);
border: solid green 1px;
} }
.dirty { .dirty {
background-color: rgba(128,128,0,0.5); background-color: rgba(128,128,0,0.5);
@ -184,7 +189,6 @@ label {
background-color: rgba(256,0,0,0.5); background-color: rgba(256,0,0,0.5);
} }
.hidden { display:none; } .hidden { display:none; }
ul.preview li:nth-child(-n+10) { ul.preview li:nth-child(-n+10) {
@ -234,6 +238,9 @@ input, select {
max-width: 64px; max-width: 64px;
max-height: 64px; max-height: 64px;
} }
#avatar {
float: left;
}
.comment { .comment {
border-radius:25px; border-radius:25px;
@ -268,8 +275,7 @@ input, select {
.c3 { font-size: x-small; font-style: italic; } .c3 { font-size: x-small; font-style: italic; }
@media print { @media print {
body {background-color:white;color:black;} body {background-color:white;color:black;}
header,footer,.postcomment,.actionlink,nav .control,.actionlink,nav { display:none;}
{ display:none;}
} }
@media all and (min-width: 640px) { @media all and (min-width: 640px) {

@ -0,0 +1,40 @@
2015-10-08 Paul Schneider <paul@pschneider.fr>
* BlogsController.cs: implements a method to update the photo
url
* style.css: yastyle
* AdminController.cs: refactoring the notification:
Introduces a static `Notice` method, server side, to populate
an array
in `ViewData`, used in the paster page.
* BlogsController.cs: Controls the photo update
* YavscHelpers.cs:
* yavsc.circles.js:
* HomeController.cs:
* GoogleController.cs: notification refactoring
* App.master: - notification refactoring
- html structure in the `nav`
* hallo.js: event 'hallomodified' now also occurs at image
modifications
* to-markdown.js: ?Fixes? html images alt text and title to
Markdown
* yavsc.js: implements the photo in database
* Edit.aspx: A nicer bill edition, with a photo
* UserPost.aspx: Displays the photo
* UserPosts.aspx: Fixes the new usage of `ResultPages`
* Web.config: totem custo
* instdbws.sql: adds a `photo` field in the `blog` table

@ -10,6 +10,7 @@ using Yavsc.Model.Admin;
using Yavsc.Admin; using Yavsc.Admin;
using System.IO; using System.IO;
using Yavsc.Model; using Yavsc.Model;
using Yavsc.Helpers;
namespace Yavsc.Controllers namespace Yavsc.Controllers
{ {
@ -160,8 +161,7 @@ namespace Yavsc.Controllers
ViewData ["usertoremove"] = username; ViewData ["usertoremove"] = username;
if (submitbutton == "Supprimer") { if (submitbutton == "Supprimer") {
Membership.DeleteUser (username); Membership.DeleteUser (username);
ViewData["Message"]= YavscHelpers.Notice(ViewData, string.Format("utilisateur \"{0}\" supprimé",username));
string.Format("utilisateur \"{0}\" supprimé",username);
ViewData ["usertoremove"] = null; ViewData ["usertoremove"] = null;
} }
return View (); return View ();
@ -236,7 +236,7 @@ namespace Yavsc.Controllers
public ActionResult DoAddRole (string rolename) public ActionResult DoAddRole (string rolename)
{ {
Roles.CreateRole(rolename); Roles.CreateRole(rolename);
ViewData["Message"] = LocalizedText.role_created+ " : "+rolename; YavscHelpers.Notice(ViewData, LocalizedText.role_created+ " : "+rolename);
return View (); return View ();
} }
@ -274,7 +274,7 @@ namespace Yavsc.Controllers
ViewData ["useritems"] = users; ViewData ["useritems"] = users;
if (ModelState.IsValid) { if (ModelState.IsValid) {
Roles.AddUserToRole (model.UserName, adminRoleName); Roles.AddUserToRole (model.UserName, adminRoleName);
ViewData ["Message"] = model.UserName + " "+LocalizedText.was_added_to_the_role+" '" + adminRoleName + "'"; YavscHelpers.Notice(ViewData, model.UserName + " "+LocalizedText.was_added_to_the_role+" '" + adminRoleName + "'");
} else { } else {
if (admins.Length > 0) { if (admins.Length > 0) {
if (! admins.Contains (Membership.GetUser ().UserName)) { if (! admins.Contains (Membership.GetUser ().UserName)) {
@ -286,9 +286,9 @@ namespace Yavsc.Controllers
// No admin, gives the Admin Role to the current user // No admin, gives the Admin Role to the current user
Roles.AddUserToRole (currentUser, adminRoleName); Roles.AddUserToRole (currentUser, adminRoleName);
admins = new string[] { currentUser }; admins = new string[] { currentUser };
ViewData ["Message"] += string.Format ( YavscHelpers.Notice(ViewData, string.Format (
LocalizedText.was_added_to_the_empty_role, LocalizedText.was_added_to_the_empty_role,
currentUser, adminRoleName); currentUser, adminRoleName));
} }
} }
return View (model); return View (model);

@ -273,6 +273,8 @@ namespace Yavsc.Controllers
} }
else else
model.Id = BlogManager.Post (model.Author, model.Title, model.Content, model.Visible, model.AllowedCircles); model.Id = BlogManager.Post (model.Author, model.Title, model.Content, model.Visible, model.AllowedCircles);
if (model.Photo != null)
BlogManager.UpdatePostPhoto (model.Id, model.Photo);
return RedirectToAction ("UserPosts", new { user = model.Author, title = model.Title }); return RedirectToAction ("UserPosts", new { user = model.Author, title = model.Title });
} }
ViewData ["AllowedCircles"] = ViewData ["AllowedCircles"] =

@ -17,6 +17,7 @@ using Yavsc.Model.Google;
using Yavsc.Model.RolesAndMembers; using Yavsc.Model.RolesAndMembers;
using Yavsc.Helpers.Google; using Yavsc.Helpers.Google;
using Yavsc.Model.Calendar; using Yavsc.Model.Calendar;
using Yavsc.Helpers;
namespace Yavsc.Controllers namespace Yavsc.Controllers
{ {
@ -100,7 +101,7 @@ namespace Yavsc.Controllers
AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg);
if (gat == null) { if (gat == null) {
ViewData ["Message"] = msg; YavscHelpers.Notice(ViewData, msg);
return View ("Auth"); return View ("Auth");
} }
SaveToken (gat); SaveToken (gat);
@ -137,7 +138,7 @@ namespace Yavsc.Controllers
OAuth2 oa = new OAuth2 (AuthGRU); OAuth2 oa = new OAuth2 (AuthGRU);
AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg);
if (gat == null) { if (gat == null) {
ViewData ["Message"] = msg; YavscHelpers.Notice(ViewData, msg);
return View (); return View ();
} }
string returnUrl = (string)Session ["returnUrl"]; string returnUrl = (string)Session ["returnUrl"];

@ -84,16 +84,9 @@ namespace Yavsc.Controllers
/// </summary> /// </summary>
public ActionResult Index () public ActionResult Index ()
{ {
/*
* A very bad idea (a redirect permanent as home page):
*
* string startPage = WebConfigurationManager.AppSettings ["StartPage"];
if (startPage != null)
Redirect (startPage);
*/
ViewData ["Message"] = LocalizedText.Welcome;
return View (); return View ();
} }
/// <summary> /// <summary>
/// Contact the specified email, reason and body. /// Contact the specified email, reason and body.
/// </summary> /// </summary>
@ -123,8 +116,7 @@ namespace Yavsc.Controllers
using (System.Net.Mail.SmtpClient sc = new SmtpClient()) using (System.Net.Mail.SmtpClient sc = new SmtpClient())
{ {
sc.Send (msg); sc.Send (msg);
ViewData ["Message"] = LocalizedText.Message_sent; YavscHelpers.Notice(ViewData, LocalizedText.Message_sent);
return View (new { email=email, reason="", body="" }); return View (new { email=email, reason="", body="" });
} }
} }

@ -14,6 +14,7 @@ using Yavsc.Model.Circles;
using System.Web.UI; using System.Web.UI;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Web.Profile; using System.Web.Profile;
using System.Web.Script.Serialization;
namespace Yavsc.Helpers namespace Yavsc.Helpers
{ {
@ -175,6 +176,23 @@ namespace Yavsc.Helpers
if (a == null || a is DBNull) return "/avatars/" + helper.Encode(username)+".png"; if (a == null || a is DBNull) return "/avatars/" + helper.Encode(username)+".png";
return helper.Encode ((string)a); return helper.Encode ((string)a);
} }
public static string JavaScript(this HtmlHelper html, object obj)
{
return JavaScript (obj);
}
public static string JavaScript(object obj)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(obj);
}
public static void Notice (ViewDataDictionary ViewData, string message) {
if (ViewData ["Notifications"] == null)
ViewData ["Notifications"] = new List<string> ();
(ViewData ["Notifications"] as List<string>).Add (message.Replace("\'","\\\'"));
}
} }
} }

@ -22,7 +22,6 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
<script src="/Scripts/yavsc.js"></script> <script src="/Scripts/yavsc.js"></script>
<asp:ContentPlaceHolder id="head" runat="server"> <asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder> </asp:ContentPlaceHolder>
<link href='http://fonts.googleapis.com/css?family=Dancing+Script:400,700' rel='stylesheet' type='text/css'/>
</head> </head>
<body> <body>
<header data-type="background" data-speed="8" > <header data-type="background" data-speed="8" >
@ -34,26 +33,33 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
</span></h1> </span></h1>
</asp:ContentPlaceHolder> </asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="header" runat="server"></asp:ContentPlaceHolder> <asp:ContentPlaceHolder ID="header" runat="server"></asp:ContentPlaceHolder>
<div id="error"><%= (ViewData["Error"]!=null)? Html.Encode(ViewData["Error"]) : "" %></div>
<div id="message"><%= Html.Encode(ViewData["Message"]) %></div> <div id="notifications">
</div>
<%if (ViewData ["Notifications"]!=null) { %>
<script>
$(document).ready(function(){
<% foreach (string notice in (IEnumerable<string>) ViewData ["Notifications"] ) { %>
Yavsc.notice('<%=notice%>');
<% } %>
});
</script>
<% } %>
</header> </header>
<nav data-type="background" data-speed="2"> <nav data-type="background" data-speed="2">
<% if (Membership.GetUser()==null) { %> <% if (Membership.GetUser()==null) { %>
<a href="<%= Url.Content("~/Account/Login/?returnUrl=") + Url.Encode( Request.Url.PathAndQuery )%>" > <a href="<%= Url.Content("~/Account/Login/?returnUrl=") + Url.Encode( Request.Url.PathAndQuery )%>" class="menuitem" >
<div class="menuitem"> <i class="fa fa-sign-in">Connexion</i>
<i class="fa fa-sign-in"></i> Connexion
</div>
</a> </a>
<% } else { %> <% } else { %>
<a href="/Blog/<%= HttpContext.Current.User.Identity.Name%>" accesskey = "B" > <a href="/Blog/<%= HttpContext.Current.User.Identity.Name%>" accesskey = "B" class="menuitem" >
<div class="menuitem">
<img src="<%=Html.AvatarUrl(HttpContext.Current.User.Identity.Name)%>" alt="vos billets" class="iconsmall" /> <img src="<%=Html.AvatarUrl(HttpContext.Current.User.Identity.Name)%>" alt="vos billets" class="iconsmall" />
<div class="hint">Vos billets</div> <span class="hint">Vos billets</span>
</div>
</a> </a>
<a href="<%= Url.Content("~/Account/Profile/" + HttpContext.Current.User.Identity.Name) %>" accesskey="L" class="menuitem"> <a href="<%= Url.Content("~/Account/Profile/" + HttpContext.Current.User.Identity.Name) %>" accesskey="L" class="menuitem">
<i class="fa fa-user"><%= HttpContext.Current.User.Identity.Name %> <i class="fa fa-user"><%= HttpContext.Current.User.Identity.Name %>
<div class="hint"> &Eacute;dition de votre profile </div></i> <span class="hint"> &Eacute;dition de votre profile </span></i>
</a> </a>
<a href="/Blogs/Post" accesskey="P" class="menuitem"> <a href="/Blogs/Post" accesskey="P" class="menuitem">
<i class="fa fa-pencil"><u>P</u>oster <i class="fa fa-pencil"><u>P</u>oster
@ -76,6 +82,7 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
<div id="copyr"> <div id="copyr">
© 2012 Totem Production. Tous droits réservés. © 2012 Totem Production. Tous droits réservés.
</div> </div>
<div class="control">
<p> <p>
<%= Html.ActionLink("Formulaire de contact","Contact","Home") %> <%= Html.ActionLink("Formulaire de contact","Contact","Home") %>
</p> </p>
@ -88,6 +95,7 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
</script> </script>
<div id="gspacer"><div class="g-plusone" data-annotation="inline" data-width="170"></div> <div id="gspacer"><div class="g-plusone" data-annotation="inline" data-width="170"></div>
</div> </div>
</div>
</footer> </footer>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load Diff

@ -507,9 +507,9 @@ module.exports = [
{ {
filter: 'img', filter: 'img',
replacement: function(content, node) { replacement: function(content, node) {
var alt = node.alt || ''; var alt = node.getAttribute("alt") || '';
var src = node.getAttribute('src') || ''; var src = node.getAttribute('src') || '';
var title = node.title || ''; var title = node.getAttribute('title') || '';
var titlePart = title ? ' "'+ title +'"' : ''; var titlePart = title ? ' "'+ title +'"' : '';
return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : ''; return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : '';
} }

@ -31,7 +31,7 @@ function onCircleChanged()
{ $('#fncirc').addClass("dirty"); } { $('#fncirc').addClass("dirty"); }
function removeCircle() { function removeCircle() {
Yavsc.message(false); Yavsc.notice(false);
var id = $(this).attr('cid'); var id = $(this).attr('cid');
$.ajax({ $.ajax({
url: CirclesApiUrl+"/Delete/"+id, url: CirclesApiUrl+"/Delete/"+id,
@ -44,12 +44,12 @@ function removeCircle() {
400: onAjaxBadInput, 400: onAjaxBadInput,
error: function (xhr, ajaxOptions, thrownError) { error: function (xhr, ajaxOptions, thrownError) {
if (xhr.status!=400) if (xhr.status!=400)
Yavsc.message(xhr.status+" : "+xhr.responseText); Yavsc.notice(xhr.status+" : "+xhr.responseText);
else Yavsc.message(false); else Yavsc.notice(false);
}}}); }}});
} }
function modifyCircle() { function modifyCircle() {
Yavsc.message(false); Yavsc.notice(false);
var id = $('#id').val(); var id = $('#id').val();
var circle = { title: $("#title").val(), id: id} ; var circle = { title: $("#title").val(), id: id} ;
$.ajax({ $.ajax({
@ -69,7 +69,7 @@ function removeCircle() {
function addCircle() function addCircle()
{ {
Yavsc.message(false); Yavsc.notice(false);
var circle = { title: $("#title").val() } ; var circle = { title: $("#title").val() } ;
$("#title").text(''); $("#title").text('');
$.ajax({ $.ajax({

@ -17,12 +17,16 @@ self.showHide = function () {
$(this).html(this.oldhtml); $(this).html(this.oldhtml);
} }
}; };
self.dimiss = function () {
self.message = function (msg) { $(this).parent().remove();
}
self.notice = function (msg, msgok) {
if (!msgok) msgok='Ok';
if (msg) { if (msg) {
$("#message").removeClass("hidden"); var note = $('<div class="notification">'+msg+'<br></div>');
$("#message").text(msg); $('<a class="actionlink"><i class="fa fa-check">'+msgok+'</i></a>').click(self.dimiss).appendTo(note);
} else { $("#message").addClass("hidden"); } }; note.appendTo("#notifications");
} };
self.onAjaxBadInput = function (data) self.onAjaxBadInput = function (data)
@ -39,10 +43,9 @@ self.message = function (msg) {
} }
self.onAjaxError = function (xhr, ajaxOptions, thrownError) { self.onAjaxError = function (xhr, ajaxOptions, thrownError) {
if (xhr.status!=400) if (xhr.status!=400)
Yavsc.message(xhr.status+" : "+xhr.responseText); Yavsc.notice(xhr.status+" : "+xhr.responseText);
else Yavsc.message(false); else Yavsc.notice(false);
} }
return self; return self;
})(); })();

@ -11,45 +11,43 @@
</asp:Content> </asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server"> <asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
<div> <span class="placard editable" for="Photo">
<% using(Html.BeginForm("ValidateEdit","Blogs")) { %> <img src="<%=Model.Photo%>" alt="photo" id="vphoto" >
<fieldset> </span>
<legend>Billet</legend> <!-- TODO? Model.Photo.(Legend|Date|Location|ref) -->
<%= Html.LabelFor(model => model.Title) %> <%= Html.ValidationMessage("Title") %> : <br> <h1 id="vtitle" for="Title" class="editable"><%=Html.Markdown(Model.Title)%></h1>
<input name="Title" id="Title" class="fullwidth"> <div id="vcontent" for="Content" class="editable">
<br>
<%= Html.LabelFor(model => model.Content) %>
<%= Html.ValidationMessage("Content") %>: <br>
<style> #Content { }
</style>
<textarea id="Content" name="Content" class="fullwidth" ><%=Html.Markdown(Model.Content)%></textarea><br>
<%= Html.CheckBox( "Visible" ) %>
<%= Html.LabelFor(model => model.Visible) %>
<%= Html.ValidationMessage("Visible", "*") %>
<br/>
<%= Html.LabelFor(model => model.AllowedCircles) %>
<%= Html.ListBox("AllowedCircles") %>
<%= Html.ValidationMessage("AllowedCircles", "*") %>
<%=Html.Hidden("Author")%>
<%=Html.Hidden("Id")%>
<input type="submit">
</fieldset>
<% } %>
</div>
<div class="post">
<h1><div id="vtitle" for="Title" class="post title editable"><%=Html.Markdown(Model.Title)%></div></h1>
<div id="vcontent" for="Content" class="post content editable">
<%=Html.Markdown(Model.Content,"/bfiles/"+Model.Id+"/")%> <%=Html.Markdown(Model.Content,"/bfiles/"+Model.Id+"/")%>
</div> </div>
</div> <span id="viewsource" class="actionlink">
<i class="fa fa-code">View Source</i></span>
<span id="hidesource" class="actionlink hidden">
<i class="fa fa-code">Hide Source</i>
</span>
<script> <script>
function dumpprops(obj) {
var str = "";
for(var k in obj)
if (obj.hasOwnProperty(k))
str += k + " = " + obj[k] + "\n";
return (str); }
$(document).ready(function(){
$('#hidesource').click(function(){
$('#source').addClass('hidden');
$('#viewsource').removeClass('hidden');
$('#hidesource').addClass('hidden');
});
$('#viewsource').click(function(){
$('#source').removeClass('hidden');
$('#viewsource').addClass('hidden');
$('#hidesource').removeClass('hidden');
});
jQuery('.placard').hallo({plugins: {'hallo-image-insert-edit': { lang: 'fr' } } });
jQuery('#vtitle').hallo({ jQuery('#vtitle').hallo({
plugins: { plugins: {
'halloformat': {}, 'halloformat': {},
@ -67,12 +65,6 @@ jQuery('#vcontent').hallo({
'hallo-image-insert-edit': { 'hallo-image-insert-edit': {
lang: 'fr' lang: 'fr'
}, },
'halloimage': {
searchUrl: apiBaseUrl+'/Blogs/SearchFile/'+$('#Id').val(),
uploadUrl: apiBaseUrl+'/Blogs/PostFile/'+$('#Id').val(),
suggestions: true,
insert_file_dialog_ui_url: '<%= Url.Content("~/Blog/ChooseMedia/?id="+Model.Id) %>'
},
'halloreundo': {}, 'halloreundo': {},
'hallocleanhtml': { 'hallocleanhtml': {
format: false, format: false,
@ -82,7 +74,6 @@ jQuery('#vcontent').hallo({
'em', 'em',
'strong', 'strong',
'br', 'br',
'div',
'ol', 'ol',
'ul', 'ul',
'li', 'li',
@ -132,10 +123,19 @@ var updateHtml = function(id,content) {
jView.html(html); jView.html(html);
}; };
jQuery('.placard').bind('hallomodified', function(event, data) {
// TODO get image source from data.content
$('#'+this.attributes["for"].value).val(
$('#vphoto').attr('src'));
});
// Update Markdown every time content is modified // Update Markdown every time content is modified
jQuery('.editable').bind('hallomodified', function(event, data) { var onMDModified = ( function (event, data) {
showSource(this.attributes["for"].value, data.content); showSource(this.attributes["for"].value, data.content);
}); });
jQuery('#vtitle').bind('hallomodified', onMDModified);
jQuery('#vcontent').bind('hallomodified', onMDModified);
jQuery('#Content').bind('keyup', function() { jQuery('#Content').bind('keyup', function() {
updateHtml(this.id, this.value); updateHtml(this.id, this.value);
}); });
@ -145,7 +145,7 @@ var updateHtml = function(id,content) {
showSource("Title",jQuery('#vtitle').html()); showSource("Title",jQuery('#vtitle').html());
showSource("Content",jQuery('#vcontent').html()); showSource("Content",jQuery('#vcontent').html());
});
</script> </script>
@ -153,8 +153,8 @@ var updateHtml = function(id,content) {
function submitFilesTo(method) function submitFilesTo(method)
{ {
var data = new FormData($('#uploads').get()[0]); var data = new FormData($('#frmajax').get()[0]);
Yavsc.message('Submitting via '+method); Yavsc.notice('Submitting via '+method);
$.ajax({ $.ajax({
url: apiBaseUrl+'/Blogs/'+method+'/'+$('#Id').val(), url: apiBaseUrl+'/Blogs/'+method+'/'+$('#Id').val(),
type: "POST", type: "POST",
@ -163,7 +163,7 @@ function submitFilesTo(method)
contentType: false, contentType: false,
success: function(data) { success: function(data) {
$('#Content').val(data+"\n"+$('#Content').val()); $('#Content').val(data+"\n"+$('#Content').val());
Yavsc.message(false); Yavsc.notice(false);
}, },
error: Yavsc.onAjaxError, error: Yavsc.onAjaxError,
}); });
@ -174,8 +174,27 @@ function submitImport()
function submitFile() function submitFile()
{ submitFilesTo('PostFile'); } { submitFilesTo('PostFile'); }
function submitBaseDoc()
{
var data = new FormData($('#frmajax').get()[0]);
Yavsc.notice('Submitting via '+method);
$.ajax({
url: apiBaseUrl+'/Blogs/'+method+'/'+$('#Id').val(),
type: "POST",
data: data,
processData: false,
contentType: false,
success: function(data) {
$('#Content').val(data+"\n"+$('#Content').val());
Yavsc.notice('Posted updated');
},
error: Yavsc.onAjaxError,
});
}
</script> </script>
<form id="uploads" method="post" enctype="multipart/form-data"> <form id="frmajax">
<fieldset> <fieldset>
<legend>Fichiers attachés</legend> <legend>Fichiers attachés</legend>
<input type="file" name="attached" id="postedfile" multiple> <input type="file" name="attached" id="postedfile" multiple>
@ -183,6 +202,31 @@ function submitFile()
<input type="button" value="importer les documents" onclick="submitImport()"> <input type="button" value="importer les documents" onclick="submitImport()">
</fieldset> </fieldset>
</form> </form>
<% using(Html.BeginForm("ValidateEdit","Blogs")) { %>
<fieldset>
<legend>Contrôle d'accès au Billet</legend>
<%= Html.LabelFor(model => model.Visible) %> : <%= Html.CheckBox( "Visible" ) %>
<i id="note_visible">Note: Si un ou plusieurs cercles sont séléctionnés ici,
le billet ne sera visible qu'aux membres de ces cercles.</i>
<%= Html.ValidationMessage("Visible", "*") %>
<%= Html.LabelFor(model => model.AllowedCircles) %>
<%= Html.ListBox("AllowedCircles") %>
<%= Html.ValidationMessage("AllowedCircles", "*") %>
</fieldset>
<fieldset id="source" class="hidden">
<%=Html.Hidden("Author")%>
<%=Html.Hidden("Id")%>
<%= Html.LabelFor(model => model.Photo) %>
<%=Html.TextBox("Photo")%>
<%=Html.ValidationMessage("Photo")%><br>
<%= Html.LabelFor(model => model.Title) %>
<%=Html.TextBox("Title")%>
<%=Html.ValidationMessage("Title")%><br>
<%=Html.TextArea("Content")%>
<%=Html.ValidationMessage("Content")%>
</fieldset>
<i class="af af-check actionlink"><input type="submit" id="validate" value="Valider"></i>
<% } %>
<aside> <aside>
Id:<%= Html.ActionLink( Model.Id.ToString() , "UserPost", new { user= Model.Author, title=Model.Title, id = Model.Id }, new { @class = "usertitleref actionlink" }) %> Id:<%= Html.ActionLink( Model.Id.ToString() , "UserPost", new { user= Model.Author, title=Model.Title, id = Model.Id }, new { @class = "usertitleref actionlink" }) %>

@ -4,7 +4,7 @@
</asp:Content> </asp:Content>
<asp:Content ContentPlaceHolderID="overHeaderOne" ID="header1" runat="server"> <asp:Content ContentPlaceHolderID="overHeaderOne" ID="header1" runat="server">
<h1 class="blogtitle"><% if (ViewData["Avatar"]!=null) { %> <h1 class="blogtitle"><% if (ViewData["Avatar"]!=null) { %>
<img src="<%=ViewData["Avatar"]%>" alt="" id="logo"/> <img src="<%=ViewData["Avatar"]%>" alt="avatar" id="avatar"/>
<% } %> <% } %>
<%= Html.ActionLink(Model.Title,"UserPost", new{user=Model.Author, title = Model.Title}, null) %> <%= Html.ActionLink(Model.Title,"UserPost", new{user=Model.Author, title = Model.Title}, null) %>
<span> - <%= Html.ActionLink((string)ViewData ["BlogTitle"] ,"UserPosts",new{user=Model.Author}, null) %> <span> - <%= Html.ActionLink((string)ViewData ["BlogTitle"] ,"UserPosts",new{user=Model.Author}, null) %>
@ -18,6 +18,11 @@
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server"> <asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
<% foreach (var be in Model) { %> <% foreach (var be in Model) { %>
<div class="post"> <div class="post">
<% if (be.Photo != null) { %>
<img src="<%=Url.Content(be.Photo)%>" alt="<%=be.Title%>">
<% } %>
<%= Html.Markdown(be.Content,"/bfiles/"+be.Id+"/") %> <%= Html.Markdown(be.Content,"/bfiles/"+be.Id+"/") %>
<% string username = Membership.GetUser()==null ? null : Membership.GetUser().UserName; %> <% string username = Membership.GetUser()==null ? null : Membership.GetUser().UserName; %>
@ -32,12 +37,12 @@
<% if (Membership.GetUser()!=null) { <% if (Membership.GetUser()!=null) {
if (Membership.GetUser().UserName==be.Author) if (Membership.GetUser().UserName==be.Author)
{ %> <div class="metapost"> { %> <div class="control">
<%= Html.ActionLink("Editer","Edit", new { id = be.Id }, new { @class="actionlink" }) %> <%= Html.ActionLink("Editer","Edit", new { id = be.Id }, new { @class="actionlink" }) %>
<%= Html.ActionLink("Supprimer","RemovePost", new { id = be.Id }, new { @class="actionlink" } ) %> <%= Html.ActionLink("Supprimer","RemovePost", new { id = be.Id }, new { @class="actionlink" } ) %>
</div> <% } %> </div> <% } %>
<aside> <aside class="control">
<% using (Html.BeginForm("Comment","Blogs")) { %> <% using (Html.BeginForm("Comment","Blogs")) { %>
<%=Html.Hidden("Author")%> <%=Html.Hidden("Author")%>
<%=Html.Hidden("Title")%> <%=Html.Hidden("Title")%>

@ -42,7 +42,6 @@
<form runat="server" id="form1" method="GET"> <form runat="server" id="form1" method="GET">
<% <%
rp1.ResultCount = (int) ViewData["RecordCount"]; rp1.ResultCount = (int) ViewData["RecordCount"];
rp1.CurrentPage = (int) ViewData["PageIndex"];
rp1.PageIndex = (int) ViewData["PageIndex"]; rp1.PageIndex = (int) ViewData["PageIndex"];
%> %>
<yavsc:ResultPages id="rp1" Action = "?pageIndex={0}" runat="server"> <yavsc:ResultPages id="rp1" Action = "?pageIndex={0}" runat="server">

@ -259,8 +259,8 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add key="SmtpServer" value="smtp.free.fr" /> <add key="SmtpServer" value="smtp.free.fr" />
<add key="AdminEMail" value="paulschneider@free.fr" /> <add key="AdminEMail" value="paulschneider@free.fr" />
<add key="OwnerEMail" value="" /> <add key="OwnerEMail" value="" />
<add key="Name" value="Totem production" /> <add key="Name" value="TOTEM PRODUCTION" />
<add key="DefaultController" value="Blogs" /> <add key="DefaultController" value="Home" />
<add key="DefaultAvatar" value="/images/noavatar.png;image/png" /> <add key="DefaultAvatar" value="/images/noavatar.png;image/png" />
<add key="RegistrationMessage" value="/RegistrationMail.txt" /> <add key="RegistrationMessage" value="/RegistrationMail.txt" />
<!-- <add key="ClientValidationEnabled" value="true" /> --> <!-- <add key="ClientValidationEnabled" value="true" /> -->

@ -171,6 +171,7 @@ CREATE TABLE blog
bcontent text NOT NULL, bcontent text NOT NULL,
visible boolean NOT NULL, visible boolean NOT NULL,
_id bigserial NOT NULL, _id bigserial NOT NULL,
photo character varying(512),
CONSTRAINT blog_pkey PRIMARY KEY (_id), CONSTRAINT blog_pkey PRIMARY KEY (_id),
CONSTRAINT bloguser FOREIGN KEY (applicationname, username) CONSTRAINT bloguser FOREIGN KEY (applicationname, username)
REFERENCES users (applicationname, username) MATCH SIMPLE REFERENCES users (applicationname, username) MATCH SIMPLE
@ -180,6 +181,8 @@ WITH (
OIDS=FALSE OIDS=FALSE
); );
COMMENT ON COLUMN blog.photo IS 'a photo url, supposed to be the main photo
related to this post';
CREATE TABLE blfiles CREATE TABLE blfiles
( (

@ -28,6 +28,15 @@ namespace Yavsc.Model.Blogs
} }
} }
/// <summary>
/// Gets or sets the photo.
/// </summary>
/// <value>The photo.</value>
public string Photo {
get;
set;
}
string title; string title;
/// <summary> /// <summary>

@ -100,6 +100,10 @@ namespace Yavsc.Model.Blogs
Provider.UpdatePost (postid, title, content, visible, cids); Provider.UpdatePost (postid, title, content, visible, cids);
} }
public static void UpdatePostPhoto (long postid, string photo)
{
Provider.UpdatePostPhoto (postid, photo);
}
/// <summary> /// <summary>
/// Finds the post. /// Finds the post.

@ -150,6 +150,13 @@ namespace Yavsc.Model.Blogs
/// </summary> /// </summary>
/// <param name="tagid">Tagid.</param> /// <param name="tagid">Tagid.</param>
public abstract void RemoveTag (long tagid); public abstract void RemoveTag (long tagid);
/// <summary>
/// Updates the post photo.
/// </summary>
/// <param name="pid">Pid.</param>
/// <param name="photo">Photo.</param>
public abstract void UpdatePostPhoto (long pid, string photo);
} }
} }

@ -1,3 +1,18 @@
2015-10-08 Paul Schneider <paul@pschneider.fr>
* BlogEntry.cs: defines the photo in the model
* BlogManager.cs: a new method to set the photo on a blog
post.
* BlogProvider.cs: the blog provider now also gives some photo
* LocalizedText.fr.Designer.cs: Reordering the french
localisation resource
* LocalizedText.fr.resx: Reorders the french localisation
resource
2015-10-04 Paul Schneider <paul@pschneider.fr> 2015-10-04 Paul Schneider <paul@pschneider.fr>
* MarkdownHelper.cs: * MarkdownHelper.cs:

@ -76,9 +76,9 @@ namespace Yavsc.Model {
} }
} }
public static string was_added_to_the_role { public static string Create {
get { get {
return ResourceManager.GetString("was_added_to_the_role", resourceCulture); return ResourceManager.GetString("Create", resourceCulture);
} }
} }
@ -88,12 +88,6 @@ namespace Yavsc.Model {
} }
} }
public static string ImportException {
get {
return ResourceManager.GetString("ImportException", resourceCulture);
}
}
public static string Title { public static string Title {
get { get {
return ResourceManager.GetString("Title", resourceCulture); return ResourceManager.GetString("Title", resourceCulture);
@ -124,12 +118,6 @@ namespace Yavsc.Model {
} }
} }
public static string DocTemplateException {
get {
return ResourceManager.GetString("DocTemplateException", resourceCulture);
}
}
public static string Ciffer { public static string Ciffer {
get { get {
return ResourceManager.GetString("Ciffer", resourceCulture); return ResourceManager.GetString("Ciffer", resourceCulture);
@ -172,9 +160,9 @@ namespace Yavsc.Model {
} }
} }
public static string User_name { public static string ImportException {
get { get {
return ResourceManager.GetString("User_name", resourceCulture); return ResourceManager.GetString("ImportException", resourceCulture);
} }
} }
@ -196,9 +184,9 @@ namespace Yavsc.Model {
} }
} }
public static string Welcome { public static string was_added_to_the_role {
get { get {
return ResourceManager.GetString("Welcome", resourceCulture); return ResourceManager.GetString("was_added_to_the_role", resourceCulture);
} }
} }
@ -220,15 +208,21 @@ namespace Yavsc.Model {
} }
} }
public static string UserName { public static string Consultant {
get { get {
return ResourceManager.GetString("UserName", resourceCulture); return ResourceManager.GetString("Consultant", resourceCulture);
} }
} }
public static string Remember_me { public static string EventWebPage {
get { get {
return ResourceManager.GetString("Remember_me", resourceCulture); return ResourceManager.GetString("EventWebPage", resourceCulture);
}
}
public static string User_List {
get {
return ResourceManager.GetString("User List", resourceCulture);
} }
} }
@ -238,15 +232,21 @@ namespace Yavsc.Model {
} }
} }
public static string Home { public static string Not_Approuved {
get { get {
return ResourceManager.GetString("Home", resourceCulture); return ResourceManager.GetString("Not Approuved", resourceCulture);
} }
} }
public static string Pdf_version { public static string Remember_me {
get { get {
return ResourceManager.GetString("Pdf_version", resourceCulture); return ResourceManager.GetString("Remember_me", resourceCulture);
}
}
public static string DocTemplateException {
get {
return ResourceManager.GetString("DocTemplateException", resourceCulture);
} }
} }
@ -292,21 +292,21 @@ namespace Yavsc.Model {
} }
} }
public static string Online { public static string Welcome {
get { get {
return ResourceManager.GetString("Online", resourceCulture); return ResourceManager.GetString("Welcome", resourceCulture);
} }
} }
public static string Not_Approuved { public static string Online {
get { get {
return ResourceManager.GetString("Not Approuved", resourceCulture); return ResourceManager.GetString("Online", resourceCulture);
} }
} }
public static string Create { public static string Home {
get { get {
return ResourceManager.GetString("Create", resourceCulture); return ResourceManager.GetString("Home", resourceCulture);
} }
} }
@ -328,21 +328,21 @@ namespace Yavsc.Model {
} }
} }
public static string role_created { public static string User_name {
get { get {
return ResourceManager.GetString("role_created", resourceCulture); return ResourceManager.GetString("User_name", resourceCulture);
} }
} }
public static string User_List { public static string DisplayName {
get { get {
return ResourceManager.GetString("User List", resourceCulture); return ResourceManager.GetString("DisplayName", resourceCulture);
} }
} }
public static string EventWebPage { public static string Pdf_version {
get { get {
return ResourceManager.GetString("EventWebPage", resourceCulture); return ResourceManager.GetString("Pdf_version", resourceCulture);
} }
} }
@ -352,15 +352,9 @@ namespace Yavsc.Model {
} }
} }
public static string DisplayName { public static string role_created {
get {
return ResourceManager.GetString("DisplayName", resourceCulture);
}
}
public static string Consultant {
get { get {
return ResourceManager.GetString("Consultant", resourceCulture); return ResourceManager.GetString("role_created", resourceCulture);
} }
} }

@ -12,62 +12,60 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="access_denied"><value>Accès refusé</value></data>
<data name="Bill_edition"><value>Édition d'un billet</value></data>
<data name="Consultant"><value>Consultant</value></data>
<data name="Count"><value>Nombre</value></data> <data name="Count"><value>Nombre</value></data>
<data name="Ciffer"><value>Chiffre</value></data> <data name="Ciffer"><value>Chiffre</value></data>
<data name="Circles"><value>Cercles</value></data>
<data name="Comment"><value>Commentaire</value></data>
<data name="Create"><value>Créer</value></data>
<data name="Date_search"><value>Demande de rendez-vous</value></data>
<data name="DocTemplateException"><value>Une erreur est survenue à la génération de votre document</value></data>
<data name="Description"><value>Description</value></data>
<data name="DisplayName"><value>Nom affiché</value></data>
<data name="entries"><value>entrées</value></data>
<data name="EndDate"><value>Date de fin</value></data>
<data name="Estimate_not_found"><value>Devis non trouvé</value></data>
<data name="EventWebPage"><value>Page web de l'événement</value></data>
<data name="Google_calendar"><value>Agenda Google</value></data>
<data name="Google_error"><value>Erreur Google : {0}</value></data>
<data name="Home"><value>Accueil</value></data>
<data name="ImgLocator"><value>URI de l'image</value></data>
<data name="ImportException"><value>Exception à l'import</value></data> <data name="ImportException"><value>Exception à l'import</value></data>
<data name="none"><value>aucun(e)</value></data> <data name="InternalServerError"><value>Erreur serveur interne</value></data>
<data name="Item_added_to_basket"><value>Article ajouté au panier</value></data>
<data name="Location"><value>Lieu</value></data>
<data name="MaxDate"><value>Date maximale du rendez-vous</value></data>
<data name="Members"><value>Membres</value></data>
<data name="Message_sent"><value>Votre message a été envoyé</value></data>
<data name="MinDate"><value>Date minimale du rendez-vous</value></data>
<data name="Modify"><value>Modifier</value></data> <data name="Modify"><value>Modifier</value></data>
<data name="My_Estimates"><value>Mes estimations</value></data>
<data name="none"><value>aucun(e)</value></data>
<data name="Not Approuved"><value>Non approuvé</value></data>
<data name="no_content"><value>pas de contenu</value></data> <data name="no_content"><value>pas de contenu</value></data>
<data name="Title"><value>Titre</value></data> <data name="Offline"><value>Hors ligne</value></data>
<data name="Description"><value>Description</value></data> <data name="Online"><value>En ligne</value></data>
<data name="Product_reference"><value>Référence produit</value></data> <data name="Pdf_version"><value>Version Pdf</value></data>
<data name="Unitary_cost"><value>Coût unitaire</value></data>
<data name="Count"><value>Nombre</value></data>
<data name="Preview"><value>Prévisualiser</value><comment>Prévisualiser le document</comment></data> <data name="Preview"><value>Prévisualiser</value><comment>Prévisualiser le document</comment></data>
<data name="Welcome"><value>Bienvenue</value><comment></comment></data> <data name="Product_reference"><value>Référence produit</value></data>
<data name="User List"><value>Liste des utilisateurs</value><comment></comment></data> <data name="ProviderId"><value>Identifiant du fournisseur</value></data>
<data name="ProviderName"><value>Nom du fournisseur</value></data>
<data name="Register"><value>Enregistez-vous</value></data> <data name="Register"><value>Enregistez-vous</value></data>
<data name="Online"><value>En ligne</value></data> <data name="Remember_me"><value>Se souvenir du mot de passe</value></data>
<data name="Offline"><value>Hors ligne</value></data>
<data name="Not Approuved"><value>Non approuvé</value></data>
<data name="Remove"><value>Supprimer</value></data> <data name="Remove"><value>Supprimer</value></data>
<data name="Pdf_version"><value>Version Pdf</value></data> <data name="role_created"><value>Rôle créé</value></data>
<data name="StartDate"><value>Date de démarrage</value></data>
<data name="Tex_version"><value>Version LaTeX</value></data> <data name="Tex_version"><value>Version LaTeX</value></data>
<data name="Title"><value>Titre</value></data>
<data name="Unitary_cost"><value>Coût unitaire</value></data>
<data name="User List"><value>Liste des utilisateurs</value><comment></comment></data>
<data name="User_name"><value>Nom d'utilisateur</value></data> <data name="User_name"><value>Nom d'utilisateur</value></data>
<data name="Google_error"><value>Erreur Google : {0}</value></data>
<data name="access_denied"><value>Accès refusé</value></data>
<data name="UserName"><value>Nom d'utilisateur</value></data>
<data name="Google_calendar"><value>Agenda Google</value></data>
<data name="Consultant"><value>Consultant</value></data>
<data name="MinDate"><value>Date minimale du rendez-vous</value></data>
<data name="MaxDate"><value>Date maximale du rendez-vous</value></data>
<data name="Date_search"><value>Demande de rendez-vous</value></data>
<data name="Remember_me"><value>Se souvenir du mot de passe</value></data>
<data name="DocTemplateException"><value>Une erreur est survenue à la génération de votre document</value></data>
<data name="Message_sent"><value>Votre message a été envoyé</value></data>
<data name="was_added_to_the_role"><value>a été ajouté au rôle</value></data> <data name="was_added_to_the_role"><value>a été ajouté au rôle</value></data>
<data name="was_added_to_the_empty_role"><value>Il n'y avait pas 'utilisateur dans le rôle '{1}'. Vous ({0}) avez été ajouté au rôle '{1}'.</value></data> <data name="was_added_to_the_empty_role"><value>Il n'y avait pas 'utilisateur dans le rôle '{1}'. Vous ({0}) avez été ajouté au rôle '{1}'.</value></data>
<data name="Welcome"><value>Bienvenue</value><comment></comment></data>
<data name="younotadmin"><value>Vous n'êtes pas administrateur</value></data> <data name="younotadmin"><value>Vous n'êtes pas administrateur</value></data>
<data name="role_created"><value>Rôle créé</value></data>
<data name="Item_added_to_basket"><value>Article ajouté au panier</value></data>
<data name="Estimate_not_found"><value>Devis non trouvé</value></data>
<data name="My_Estimates"><value>Mes estimations</value></data>
<data name="User_name"><value>Nom d'utilisateur</value></data>
<data name="Circles"><value>Cercles</value></data>
<data name="Location"><value>Lieu</value></data>
<data name="StartDate"><value>Date de démarrage</value></data>
<data name="EndDate"><value>Date de fin</value></data>
<data name="ProviderName"><value>Nom du fournisseur</value></data>
<data name="ProviderId"><value>Identifiant du fournisseur</value></data>
<data name="Comment"><value>Commentaire</value></data>
<data name="EventWebPage"><value>Page web de l'événement</value></data>
<data name="ImgLocator"><value>URI de l'image</value></data>
<data name="Home"><value>Accueil</value></data>
<data name="Bill_edition"><value>Édition d'un billet</value></data>
<data name="Create"><value>Créer</value></data>
<data name="Members"><value>Membres</value></data>
<data name="UserName"><value>Nom d'utilisateur</value></data>
<data name="DisplayName"><value>Nom affiché</value></data>
<data name="entries"><value>entrées</value></data>
<data name="InternalServerError"><value>Erreur serveur interne</value></data>
</root> </root>

Loading…