-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdata.json
1451 lines (1451 loc) · 91.9 KB
/
data.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{
"/": {
"meta title": "Reference",
"chapters": [
{
"title": "Introduction",
"topics": [
{
"contents": [
{
"text": "<p>SimplyEdit is a tool to build websites and web application user interfaces. It allows you to create an easy to use interface to edit websites or enter data. Most of this can be done without programming, you only need to add a few attributes in your HTML.</p><p>SimplyEdit divides your data into two concepts: fields and lists. A field can be any HTML element. When using SimplyEdit to edit a website, a field is any part of a webpage that is meant to be editable.</p><p>A list can also be any HTML element. But a list can contain any number of entries. Each entry can contain fields, or further lists. A list is comparable to an array of objects.</p><p>Unlike most other systems, SimplyEdit doesn't require you to define a model or schema for your data. Instead SimplyEdit reads your HTML and figures out what your data model or schema is from the attributes in the HTML.</p><p>You can still change the HTML without changing your data model, if you keep the nesting of lists and fields, and their names, identical. This is usually more than enough freedom to create completely different layouts for the same data.</p>",
"data-simply-template": "text"
}
],
"title": "Basic Concepts"
}
]
},
{
"title": "Settings",
"topics": [
{
"contents": [
{
"text": "<p>The most important settings for SimplyEdit are set as attributes on the `<script>` tag:</p>",
"data-simply-template": "text"
},
{
"code": "<script src=\"//cdn.simplyedit.io/1/simply-edit.js\"\n data-api-key = \"your-key-1234\"\n data-simply-images = \"/img/\"\n data-simply-files = \"/files/\"\n data-simply-storage = \"myStorage\"\n data-simply-endpoint = \"/\"\n data-simply-settings = \"mySettings\"\n data-simply-datasources = \"myDataSources\"\n></script>",
"data-simply-template": "code"
},
{
"text": "<p>In addition you can specify settings for specific plugins and toolbars using the variable specified in data-simply-settings, e.g.:</p>",
"data-simply-template": "text"
},
{
"code": "<script>\n window.mySettings = {\n }\n</script>",
"data-simply-template": "code"
},
{
"text": "<p>Some storage engines can have extra atributes. E.g. github uses:<br></p>",
"data-simply-template": "text"
},
{
"code": "<script src=\"//cdn.simplyedit.io/1/simply-edit.js\"\n data-api-key = \"your-key-1234\"\n data-simply-storage = \"github\"\n data-simply-repo-user = \"SimplyEdit\"\n data-simply-repo-name = \"spectral\"\n data-simply-repo-branch = \"gh-pages\"\n></script>",
"data-simply-template": "code"
},
{
"text": "<p>You can read more about the different storage engines in the Storage section.</p>",
"data-simply-template": "text"
}
],
"title": "Script attributes"
},
{
"title": "simply-text-selection and simply-text-cursor",
"contents": [
{
"text": "<p>The text toolbar allows you to specify which block and inline tags to list. Both text toolbars use the same style configuration, but you must specify both of them:<br></p>",
"data-simply-template": "text"
},
{
"code": "var textSettings = {\n block: [\n { tag: 'h2', name: 'Heading 2' },\n { tag: 'p.summary', name: 'Summary' }\n ],\n inline: [\n { tag: 'strong', name: 'Bold', icon: 'fa-bold' }\n ]\n};\n\nvar mySettings = {\n 'simply-text-cursor': textSettings,\n 'simply-text-selection': textSettings\n};",
"data-simply-template": "code"
},
{
"text": "<p>In addition you can specify sets of classes, where the user may select one per set. Each set works like a set of radio buttons:</p>",
"data-simply-template": "text"
},
{
"code": "var textSettings = {\n 'style': [\n {\n description: 'Color',\n selector: '*',\n styles: [\n {'class':'red', name: 'Red', icon: 'fa-paint-brush'},\n {'class':'green', name: 'Green', icon: 'fa-paint-brush'},\n {'class':'blue', name: 'Blue', icon: 'fa-paint-brush'}\n ]\n },{\n description: 'Emphasis',\n selector: 'h1,h2,h3,p',\n styles: [\n {'class':'highlight', name: 'Highlight', icon: 'fa-sun-o'},\n {'class':'lowlight', name: 'Lowlight', icon: 'fa-moon-o'}\n ]\n }\n ]\n};",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>Each style entry has a description, which will be shown in the popup toolbar. It has a selector, which is checked against the current selection. The styles are only shown when the current selection matches the selector.<br></p>"
}
]
},
{
"title": "simply-image",
"contents": [
{
"text": "<p>The image toolbar also supports sets of classes, just like the text toolbars:</p>",
"data-simply-template": "text"
},
{
"code": "var mySettings = {\n 'simply-image': {\n 'style' : [\n {\n description: 'Border',\n selector: 'img',\n styles: [\n {'class': 'shadow', name: 'Shadow', icon: 'fa-moon-o'},\n {'class': 'border', name: 'Border', icon: 'fa-square-o'}\n ]\n }\n ]\n }\n};",
"data-simply-template": "code"
},
{
"text": "<p>In addition, you can setup SimplyEdit to automatically use responsive images. This means that all images your users upload will be scaled to the sizes you specify. SimplyEdit will automatically choose the best fitting image size to display for each individual image. This requires you to also load the image scaler plugin:</p>",
"data-simply-template": "text"
},
{
"code": "var mySettings = {\n 'simply-image' : {\n 'responsive' : {\n 'sizes' : [ 1024, 720, 640, 320, 160 ]\n }\n },\n 'plugins' : [ 'plugin.simply-scaler.html' ]\n};",
"data-simply-template": "code"
}
]
},
{
"title": "Page templates",
"contents": [
{
"text": "<p>SimplyEdit is a simple content management system. It allows you to create new pages. Each page can have a different template. A template is just a HTML file. You can tell SimplyEdit which page templates there are like this:</p>",
"data-simply-template": "text"
},
{
"code": "var mySettings = {\n 'pageTemplates': {\n 'templates': [\n {name: 'Default', template: 'index.html'},\n {name: 'Blog post', template: 'blog.html'}\n ]\n }\n};",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>The default location for templates is in your site root in the <code>templates/</code> subdirectory.</p>"
}
]
}
]
},
{
"title": "Attributes",
"topics": [
{
"contents": [
{
"code": "<h1 data-simply-field=\"title\">Title</h1>",
"data-simply-template": "code"
},
{
"text": "<p>Makes an HTML element editable in the browser in editmode. It also adds the contents to the data store. This means that you can change the contents of the field in javascript simply by changing the javascript object, like this:</p>",
"data-simply-template": "text"
},
{
"code": "editor.pageData.title.innerHTML = 'New Title';",
"data-simply-template": "code"
},
{
"text": "<p>This attribute can be set on any HTML element. Depending on which HTML element, it will expect and set different properites:</p><ul><li><code>*</code>: innerHTML</li><li><code>A</code>: href, name, target, newwindow, nofollow and innerHTML</li><li><code>IMG</code>: src, class, alt and title</li><li><code>INPUT[type=\"text\"]</code>: value<br></li><li><code>INPUT[type=\"hidden\"]</code>: value</li><li><code>INPUT[type=\"number\"]</code>: value</li><li><code>INPUT[type=\"radio\"]</code>: checked, value, simplyData*</li><li><code>INPUT[type=\"checkbox\"]</code>: checked<br></li><li><code>SELECT</code>: value, simplyValue*</li><li><code>SELECT[multiple]</code>: selectedOptions, simplyValue*</li><li><code>OPTION</code>: value, innerHTML</li><li><code>TEXTAREA</code>: value</li><li><code>IFRAME</code>: src</li><li><code>META</code>: content</li></ul><p>Fields may not contain other fields, except when using <code>data-simply-content=\"fixed\"</code>.</p><p>Fields with the same name on the same page will always have the same content. Except when the field is part of a list entry, or if you\u2019ve specified a different path with <code>data-simply-path</code>.</p><p>A field name may contain any valid character for HTML attributes, including spaces. But the <code>.</code> character has a specific meaning, it will assume everything before the <code>.</code> is the name of an object and after the <code>.</code> is a property of that object.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-field"
},
{
"contents": [
{
"code": "<a data-simply-field=\"link\" data-simply-content=\"fixed\">\n <img data-simply-field=\"image\">\n</a>",
"data-simply-template": "code"
},
{
"text": "<p>Tells SimplyEdit what kind of content the field may contain. Expects one of the following values:</p><ul><li><code>text</code> Allow only pure text inside this field.</li><li><code style=\"font-weight: normal;\">fixed</code> Only attributes on the element are editable. The innerHTML will not be set or updated.</li><li><code>attributes</code> Only make the attributes of the element editable. By default all attributes will be stored. You can override this with the data-simply-attributes attribute.</li><li><code>template</code> The value of the field will be used to select a template. The template name must match the value of the field. If the field is not available in the data store yet, you can set a default value with the data-simply-default-value attribute.</li></ul>",
"data-simply-template": "text"
}
],
"title": "data-simply-content"
},
{
"contents": [
{
"code": "<button data-simply-field=\"product\" data-simply-content=\"attributes\"\n data-simply-attributes=\"data-item-id data-item-name data-item-price\"\n>Buy Now</button>\n<div data-simply-field=\"product.data-item-id\">1</div>\n<div data-simply-field=\"product.data-item-name\">Name</div>\n<div data-simply-field=\"product.data-item-price\">99</div>",
"data-simply-template": "code"
},
{
"text": "<p>Used in combination with <code>data-simply-content=\"attributes\"</code>, this allows you to specify which attributes are databound using SimplyEdit. The example above shows how you can use this to edit specific attributes. Each <code>div</code> above is bound to a specific attribute value. By changing the content of the <code>div</code>, you change the value of the attribute in the <code>button</code> as well.</p><p>You can also change the attributes in javascript, like this:</p>",
"data-simply-template": "text"
},
{
"code": "editor.pageData.product['data-item-name'] = 'A splendid product';",
"data-simply-template": "code"
}
],
"title": "data-simply-attributes"
},
{
"contents": [
{
"code": "<input type=\"radio\" name=\"size\" value=\"small\" data-simply-field=\"size\">Small\n<input type=\"radio\" name=\"size\" value=\"large\" data-simply-field=\"size\">Large\n<div data-simply-field=\"size\" data-simply-content=\"template\">\n <template data-simply-template=\"small\">\n Small size selected\n </template>\n <template data-simply-template=\"large\">\n Large size selected\n </template>\n</div>",
"data-simply-template": "code"
},
{
"text": "<p>Used in combination with <code>data-simply-content=\"template\"</code>, this allows you to specify which template to use for the content of the current html element. The value of the field is matched with the name of the templates listed in the field. In this case radio buttons are used to select the specific template. </p><p>You can also change the template in javascript like this:</p>",
"data-simply-template": "text"
},
{
"code": "editor.pageData.size = 'small';",
"data-simply-template": "code"
},
{
"text": "<p>If no template is specified, nothing is shown. You can specify a default value in the HTML like this:</p>",
"data-simply-template": "text"
},
{
"code": "<div data-simply-field=\"size\" data-simply-content=\"template\" \n data-simply-default-value=\"small\">",
"data-simply-template": "code"
}
],
"title": "data-simply-template"
},
{
"contents": [
{
"code": "<ul data-simply-list=\"items\">\n <template>\n <li>\n <a data-simply-field=\"entry\">Entry</a>\n </li>\n </template>\n</ul>",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>Specifies the content is a list of items. Each item can have multiple fields. One or more templates may be defined for the items. If a specific template is selected for an item, the template name will be stored inside the item as data-simply-template. When rendering the list, if no matching template is found, the first template specified will be used.</p>"
},
{
"code": "<dl data-simply-list=\"items\">\n <template data-simply-template=\"topic\">\n <dt data-simply-field=\"entry\">Topic</dt>\n </template>\n <template data-simply-template=\"definition\">\n <dd data-simply-field=\"entry\">Definition</dd>\n </template>\n</dl>",
"data-simply-template": "code"
},
{
"text": "<p>In this example you can choose to add a topic (<code>dt</code>) or definition (<code>dd</code>) in a list. The resulting structure will look like this:</p>",
"data-simply-template": "text"
},
{
"code": "\"items\": [\n {\n \"data-simply-template\": \"topic\",\n \"entry\": {\n \"innerHTML\": \"A Topic\"\n }\n },\n {\n \"data-simply-template\": \"definition\",\n \"entry\": {\n \"innerHTML\": \"A definition of this topic\"\n }\n }\n]",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>Lists may be nested inside other lists:</p>"
},
{
"data-simply-template": "code",
"code": "<ul data-simply-list=\"menu\">\n <template data-simply-template=\"item\">\n <li>\n <a data-simply-field=\"item\">Item</a>\n </li>\n </template>\n <template data-simply-template=\"submenu\">\n <li>\n <a data-simply-field=\"submenu item\">Submenu</a>\n <ul data-simply-list=\"menu\">\n <template data-simply-template=\"item\">\n <li>\n <a data-simply-field=\"item\">Item</a>\n </li>\n </template>\n </ul>\n </li>\n </template>\n</ul>"
}
],
"title": "data-simply-list"
},
{
"contents": [
{
"code": "<ul data-simply-list=\"items\" data-simply-sortable>\n <template>\n <li>\n <a data-simply-field=\"entry\">Entry</a>\n </li>\n </template>\n</ul>",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>Only valid in combination with <code>data-simply-list</code>, this tells SimplyEdit to allow the editor to drag and drop entries within the list.</p>"
}
],
"title": "data-simply-sortable"
},
{
"contents": [
{
"code": "<article data-simply-list=\"sections\">\n <template data-simply-template=\"text\">\n <section class=\"text\" data-simply-field=\"text\"></section>\n </template>\n <template data-simply-template=\"heading\">\n <h2 class=\"heading\" data-simply-field=\"heading\"></h2>\n </template>\n</article>\n",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>Only valid inside a <code>data-simply-list</code>, or a <code>data-simply-field</code> with <code>data-simply-content=\"template\"</code>. This specified the name of the template. This is used to select and to store the selected template. If you have more than one template, this attribute is required and must be unique within the same list or field.</p>"
}
],
"title": "data-simply-template"
},
{
"contents": [
{
"code": "<template data-simply-template=\"text\" data-simply-icon=\"font\">",
"data-simply-template": "code"
},
{
"text": "<p>This tells SimplyEdit which icon to show in the toolbars when selecting a template. Any icon from Font Awesome 4 can be used.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-icon"
},
{
"contents": [
{
"code": "<section class=\"blog\" data-simply-list=\"blog\" data-simply-data=\"rss\">\n <template>\n <article>\n <h1 data-simply-field=\"title\">Title</a>\n <p data-simply-field=\"description\">Description</p>\n <p><a data-simply-field=\"link\">link</a></p>\n </article>\n </template>\n</section>",
"data-simply-template": "code"
},
{
"text": "<p>Connects a list to a data source. Read the chapter Data Sources for more information on their use.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-data"
},
{
"contents": [
{
"code": "<select data-simply-list=\"years\" data-simply-entry=\"year\">\n <template>\n <option data-simply-field=\"year\">2017</option>\n </template>\n</select>",
"data-simply-template": "code"
},
{
"code": "editor.pageData.years = [ 2015, 2016, 2017 ];",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>Specifies which name to use for direct values of an array. In this case the years array is a simple list of values, not objects. So <code>data-simply-entry=\"year\"</code> tells SimplyEdit to match the field <code>year</code> with the full entry in the array.</p>"
}
],
"title": "data-simply-entry"
},
{
"contents": [
{
"text": "<p>This attribute is set automatically by SimplyEdit on each item in a list. It can be used to prefill a list in your HTML. Each item with this attribute is automatically appended to the list, even if it is not in the list data yet. This allows you to create a template with a list with a few list items set by default.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-list-item"
},
{
"contents": [
{
"code": "<nav>\n <ul data-simply-list=\"menu\" data-simply-path=\"/\">\n <template data-simply-template=\"item\">\n <li>\n <a data-simply-field=\"item\">Item</a>\n </li>\n </template>\n </ul>\n</nav>",
"data-simply-template": "code"
},
{
"text": "<p>Specifies the path to store all child data in. Most useful for site navigation and global footers.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-path"
},
{
"contents": [
{
"text": "<p>This attribute is automatically set by SimplyEdit on any item that is user selectable, like list items, fields, etc.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-selectable"
},
{
"contents": [
{
"text": "<p>Any element marked with this attribute will be hidden when in edit mode. This allows you to hide certain elements that would otherwise interfere with editing a webpage.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-hidden"
},
{
"contents": [
{
"text": "<p>Used to make static images responsive. A static image is an image which is not editable, e.g. a website logo. By using this attribute instead of the normal src attribute, SimplyEdit will look for the best fitting size and set the src automatically. Remember that the image must be uploaded with SimplyEdit so that all the sizes set in the image settings are available.</p>",
"data-simply-template": "text"
},
{
"code": "<img data-simply-src=\"logo.png\" alt=\"my logo\">",
"data-simply-template": "code"
}
],
"title": "data-simply-src"
},
{
"contents": [
{
"text": "<p>This attribute is automatically set by SimplyEdit on the <code>body</code> element, when the editor is started. This allows you to check if the editor is started in javascript as well as css:</p>",
"data-simply-template": "text"
},
{
"code": "body[data-simply-edit] main {\n padding-top: 60px;\n}",
"data-simply-template": "code"
}
],
"title": "data-simply-edit"
},
{
"contents": [
{
"text": "<p>Used in combination with <code>data-simply-content=\"template\"</code>, this allows you to specify the default template to use, if no other data is set.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-default-value"
},
{
"contents": [
{
"text": "<p>Only applicable on the SimplyEdit script tag, this is your personal API key that is connected to your websites domain. Without a valid key SimplyEdit will not start the editor. Everything else will work without a valid key.</p>",
"data-simply-template": "text"
}
],
"title": "data-api-key"
},
{
"contents": [
{
"text": "<p>Only applicable on the SimplyEdit script tag, this specifies the name of the settings variable. To read more about the settings, see the chapter titled 'Settings'.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-settings"
},
{
"contents": [
{
"text": "<p>Only applicable on the SimplyEdit script tag, this specifies the URL endpoint where SimplyEdit will store the site data. This does not include the images and files, they have a seperate attribute.</p><p>The default storage layer in SimplyEdit will store data through a <code>PUT</code> request to this storage endpoint URL, appended with <code>data/data.json</code>.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-endpoint"
},
{
"contents": [
{
"text": "<p>Specifies the root URL to store and retrieve images.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-images"
},
{
"contents": [
{
"text": "<p>Specifies the root URL to store and retrieve files.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-files"
},
{
"contents": [
{
"text": "<p>This attribute is set by SimplyEdit automatically, to keep track of all the fields and lists that have been 'stashed'. This means their data is collected and will be sent to the storage layer to save.</p>",
"data-simply-template": "text"
}
],
"title": "data-simply-stashed"
}
]
},
{
"title": "Data Binding",
"topics": [
{
"contents": [
{
"text": "<p>SimplyEdit automatically initializes a databinding for each field and list it finds in the HTML template. It connects all the data in your data.json to their corresponding fields and lists in the HTML. There is no initialization needed.</p>",
"data-simply-template": "text"
}
],
"title": "Setup"
},
{
"contents": [
{
"text": "<p>All the fields and lists are added to <code>editor.pageData</code>, which is a shortcut for <code>editor.currentData[{currentpath}]</code>.</p><p>When your site data is loaded from storage, e.g. the data.json file, this data will be inserted into <code>editor.currentData</code>. All the fields in your json that correspond to a field or list in your HTML are automatically bound to their DOM elements. Whenever the <code>editor.currentData</code> changes, so will the DOM.</p><p>The other way around also works. Whenever the DOM changes, SimplyEdit will notice and push the change on its internal stack. With a slight delay this change will then be applied to the <code>editor.currentData</code> as well. This change is not instantanious, by design.</p>",
"data-simply-template": "text"
}
],
"title": "Update flow"
},
{
"contents": [
{
"text": "<p>You can hook into the databinding flow with a few events. These events are fired by the databinding layer and you can listen in on them:</p><ul><li><code>databind:resolved</code> is fired on the document whenever a change in data is rendered in the DOM.<br></li><li><code>databind:elementresolved</code> is fired on each DOM element whenever a change in data is rendered there.</li></ul><p>In addition these events you can fire yourself to influence the databinding resolution and rendering. You will only need these when working with very large sets of data and changes. Otherwise just let SimplyEdit handle all this automatically.</p><ul><li><code>databinding:valuechanged</code> Fire this when a value is changed in the DOM, but SimplyEdit isn't aware of it. This can happen when you change some elements values through javascript.</li><li><code>databinding:pause</code> Fire this when you are working on a set of changes in a time sensitive javascript routine. Don't forget to fire <code>databinding:resume</code> later and perhaps <code>databinding:valuechanged</code>.</li><li><code>databinding:resume</code> Start the normal databinding flow up again after pausing it.</li></ul>",
"data-simply-template": "text"
}
],
"title": "Events"
}
]
},
{
"title": "Data Sources",
"topics": [
{
"contents": [
{
"data-simply-template": "text",
"text": "<p>A data source is a way to use lists of data, without two-way databinding. This has a few advantages:</p><ul><li>Performance: rendering large lists of data performs much better with a data source instead of a data-simply-list.<br></li><li>The contents of a datasource are not stored as-is in SimplyEdit when the user presses save.</li></ul><p>A datasource is automatically loaded and rendered by SimplyEdit. A datasource can only be applied on a list.</p><p>A minimal datasource looks like this:</p>"
},
{
"data-simply-template": "code",
"code": "editor.addDataSource('myDataSource', {\n load: function(el, callback) {\n var data = [1, 2, 3, 4];\n callback(data);\n }\n});"
},
{
"data-simply-template": "text",
"text": "<p>The name is used to apply the datasource to a SimplyEdit list:</p>"
},
{
"data-simply-template": "code",
"code": "<select data-simply-list=\"options\" data-simply-data=\"myDataSource\" data-simply-entry=\"entry\">\n <template>\n <option data-simply-field=\"entry\"></option>\n </template>\n</select>"
},
{
"data-simply-template": "text",
"text": "<p><em>Note</em>: Because the data in the datasource doesn't consists of objects with properties, the code above uses the <code>data-simply-entry</code> attribute to define a name (<code>entry</code>) for each entry in the data array.<br></p>"
}
],
"title": "Introduction"
},
{
"title": "editor.addDataSource",
"contents": [
{
"text": "<p>A full list of arguments to addDataSource looks like this:</p>",
"data-simply-template": "text"
},
{
"code": "editor.addDataSource(\n 'myDataSource',\n load: data, // may also be a function, see previous example\n save: function(stash) {\n },\n get: function(list) {\n },\n set: function(list, listData) {\n },\n applyOnce: true //false is the default\n);",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>The load and save methods manage data retrieval and saving to external sources. The get and set methods manage the same for the internal data retrieval and saving. For example, you can define a datasource that loads data from a Google Spreadsheet and updates the spreadsheet when data is changed in the SimplyEdit editor. For this you use the load and save methods.</p><p>However if you want the user to select which Google spreadsheet to load, you use the get and set methods to store and retrieve this information in the data.json.</p><p>The methods are called in this order:<br></p><p>On loading the <code>data.json</code>:</p><ul><li><code>set(listElement, listData)</code></li><li><code>load(listElement, callback) -> void, call callback(resultListData)</code></li></ul><p>On pressing save</p><ul><li><code>get(listElement) -> returns data to be saved in the data.json</code> </li><li><code>save(stash) -> void</code></li></ul><p>Finally SimplyEdit saves the <code>data.json</code></p><p>In general you probably only need the load, optionally with the save method. Or you just want the get and set methods. Here are a few use cases with the methods you need to override:</p><ul><li>An RSS reader for a specific RSS feed<br>Just needs a load method for a specific URL</li><li>A generic RSS reader<br>Uses a set method to add an attribute to the list specifying which RSS URL to load.<br>Uses the load method to read this attribute and return the RSS data as json.<br>And finally uses the get method to return the RSS URL, which gets saved in the data.json.</li></ul><p>You only need to use the <code>save()</code> method if you want to save data to an external resource, after it is edited in SimplyEdit.</p>"
}
]
},
{
"title": "The stash",
"contents": [
{
"text": "<p>So what is this stash mentioned in the previous topic? SimplyEdit needs to gather all the data in the current page and send it to the server when you press the save button. It does this by collecting it in something called the stash. But data from a datasource shouldn't get saved in the data.json, so it also creates a stash per datasource.</p><p>This datasource stash contains all the fields and their data, as used in each list that uses the datasource. So if you have a single datasource used by multiple lists, the get() and save() methods on the datasource are called for each list.</p><p>The stash contains the following data:</p><ul><li><code>list</code>: the list element that uses the datasource</li><li><code>dataPath</code>: a representation of the field and list nesting in this page, similar to a JSON pointer</li><li><code>dataName</code>: the name of the list as stored in the <code>data.json</code></li><li><code>data</code>: the list data as returned by <code>load()</code> and perhaps edited by the user</li></ul><p>When you add your own <code>save()</code> method, it is your responsibility to do whatever you need to do to save any changes made by the user back to the external resource, using the information above.</p>",
"data-simply-template": "text"
}
]
}
]
},
{
"title": "Plugins",
"topics": [
{
"title": "Toolbars",
"contents": [
{
"data-simply-template": "text",
"text": "<p>SimplyEdit uses a simple plugin system. For historic reasons the terms plugin and toolbars are considered equivalent. Each plugin or toolbar consists of a single file that may contain HTML, CSS and Javascript. Consider the toolbar.simply-icon.html plugin:</p>"
},
{
"data-simply-template": "code",
"code": "<section id=\"simply-icon\" class=\"simply-section\">\n <h1>Insert icon toolbar</h1>\n <div class=\"simply-toolbar\">\n <ul class=\"simply-buttons\">\n <li><button data-simply-action=\"simply-symbol\">\n <i class=\"fa fa-rocket\"></i>Insert icon\n </button></li>\n </ul>\n </div>\n</section>\n<script type=\"text/javascript\">\n editor.addToolbar({\n \"name\" : \"simply-icon\",\n \"filter\" : {\n \"selector\" : \"i.fa\"\n }\n });\n</script>"
},
{
"data-simply-template": "text",
"text": "<p>This defines a toolbar that allows you to insert an icon using the Font Awesome icon set. Each plugin that has its own UI should define this inside a HTML <code><section></code> tag with the class name <code>simply-section</code> and a unique ID. You may define multiple such sections inside a single plugin.</p><p>Then add a <script> tag in which you call the SimplyEdit API to do the real work. In this case the <code>addToolbar()</code> method is called, which requires the name (or ID) of the toolbar definition specified in the HTML earlier. And it requires a filter, which consists of one or more CSS selectors that define when the toolbar becomes visible.</p><p>SimplyEdit only allows one toolbar to be visible at any time. It uses the filter and the selectors inside them to calculate which toolbar has precedence. You can make the filter more specific by adding parent selectors:</p>"
},
{
"data-simply-template": "code",
"code": "editor.addToolbar({\n name: 'simply-image',\n filter: {\n selector: 'IMG',\n parent: {\n selector: '*'\n }\n }\n});"
},
{
"data-simply-template": "text",
"text": "<p>In this case the image toolbar adds a parent selector that matches everything. This makes the image toolbar filter have a higher precedence than other toolbars that might match on the <code>IMG</code> tag. If you create your own toolbars, you may have to experiment a bit with the correct filter setting. You can ask SimplyEdit to show what scores it has calculated for each toolbar it considered:</p>"
},
{
"data-simply-template": "code",
"code": "console.log(editor.context.explain);"
},
{
"data-simply-template": "text",
"text": "<p>This will print the information for each toolbar SimplyEdit has considered and which toolbar has won. So:</p>"
},
{
"data-simply-template": "code",
"code": "console.log(editor.context.explain.validFilters);"
},
{
"data-simply-template": "text",
"text": "<p>Will show all the filters that match the current selection, and their respective scores. Higher is better.<br></p><p>Toolbars can also define actions and an init and update method:</p>"
},
{
"data-simply-template": "code",
"code": "editor.addToolbar({\n name: 'my-toolbar',\n filter: {\n selector: 'a.my-link',\n parent: {\n selector: '*'\n }\n },\n actions: {\n 'my-action': function(el) {\n alert('This is my action');\n }\n },\n init: function(config) {\n // intialize your settings\n },\n update: function(toolbar) {\n // update the visible toolbar\n }\n});"
},
{
"data-simply-template": "text",
"text": "<p>The <code>init</code> function is called once, when the editor starts. It passes any information set for this toolbar in the global settings variable, the one named in the script tags <code>data-simply-settings</code> parameter.</p><p>The <code>update</code> function is called whenever the selection changes and this toolbar is visible. It has one argument: the toolbars <code>section</code> element.</p>"
}
]
},
{
"title": "Other plugins",
"contents": [
{
"data-simply-template": "text",
"text": "<p>Besides toolbars you can add other plugins as well. The only difference really is whether or not you call the <code>editor.addToolbar()</code> method. If you create a plugin that is not strictly a toolbar, consider using the <code>editor.plugins</code> namespace to add your own. e.g.:</p>"
},
{
"data-simply-template": "code",
"code": "<script>\n editor.plugins.myPlugin = (function() {\n return {\n doSomething: function() {\n alert('This does something');\n }\n };\n })();\n</script>"
}
]
}
]
},
{
"title": "Actions",
"topics": [
{
"contents": [
{
"data-simply-template": "text",
"text": "<p>Actions are labels that connect a user interface or HTML element to a specific javascript function. Actions are defined either in toolbars, in the <code>actions</code> parameter of the <code>editor.addToolbar()</code> method, or as seperate actions using the <code>editor.addAction()</code> method.</p><p>Actions are added to a toolbar button or input element, as a <code>data-simply-action</code> attribute:</p>"
},
{
"code": "<button data-simply-action=\"insert-symbol\">Insert Symbol</button>",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>You can create as many buttons or input elements with a certain action as you like. You can specify any action that is added by any toolbar, as long as that toolbar or action is loaded. All actions are defined globally.</p><p><em>Note</em>: actions are only loaded when the toolbars are. So if the editor isn't started, the actions aren't available. SimplyEdit doesn't even check for any <code>data-simply-action</code> attribute untill the toolbars are loaded. So although you can add actions to elements in the normal page content, they will only work once the editor is started.</p>"
}
],
"title": "Introduction"
},
{
"title": "addAction",
"contents": [
{
"text": "<p>You can specify an action explicitly like this:</p>",
"data-simply-template": "text"
},
{
"data-simply-template": "code",
"code": "editor.addAction('my-action', editor.plugins.myPlugin.myAction);"
},
{
"data-simply-template": "text",
"text": "<p>Actions only require a name and a method to call. The method has only one argument: the element with the <code>data-simply-action</code> attribute that triggered this action:</p>"
},
{
"data-simply-template": "code",
"code": "editor.plugins.myPlugin.myAction = function(el) {\n alert('doing stuff...');\n}"
}
]
}
]
},
{
"title": "Events",
"topics": [
{
"title": "simply-content-loaded",
"contents": [
{
"text": "<p>Fires on the <code>document</code> when SimplyEdit is finished initializing the page content. It has no parameters. Use this event instead of DocumentReady.</p>",
"data-simply-template": "text"
},
{
"code": "document.addEventListener('simply-content-loaded', function() {\n // page content is loaded in the dom, so now you can work with it\n});",
"data-simply-template": "code"
}
]
},
{
"title": "simply-editmode",
"contents": [
{
"text": "<p>Fires on the <code>document</code> when the user starts the editor. You can\u2019t prevent this.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-toolbars-loaded",
"contents": [
{
"text": "<p>Fires on the <code>document</code> when the editor is finished loading all the toolbars and plugins. Use this to change or append to the toolbars.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-data-changed",
"contents": [
{
"text": "<p>Fires on the <code>document</code> whenever data managed by SimplyEdit changes. It is fired after the change is resolved, so the DOM and the Editor should be in sync.</p><p>Parameters: - dataBinding</p>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-data-applied",
"contents": [
{
"text": "<p>Fires on a <code>data-simply-list</code> after it has been updated.</p><p>Parameter: - Target list element.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-data-saved",
"contents": [
{
"text": "<p>Fires on the <code>document</code> after <code>editor.currentData</code> is saved by a storage layer. </p><p>Parameter:<br></p><ul><li><code>newData</code> The saved data as returned by the storage layer.</li><li><code>*</code> Any other parameters may be set by the storage layer.</li></ul>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-storage-init",
"contents": [
{
"text": "<p>Fires on the <code>document</code> immediately after the storage layer has been initialized.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-storage-file-saved",
"contents": [
{
"text": "<p>Fires on the <code>document</code> after a file is saved by the storage layer. This event can be cancelled by calling <code>preventDefault()</code> on it. The file will still be saved, but the files dialog won't be updated.</p><p>Parameters</p><ul><li><code>path</code> The path that was passed to the storage layer.</li><li><code>response</code> The http responseText</li><li><code>message</code> An error message, if <code>error</code> is <code>true</code></li><li><code>error</code> Boolean. True if an error occured. The error message is in <code>message</code>.</li></ul>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-storage-file-deleted",
"contents": [
{
"text": "<p>Fires on the <code>document</code> after a file has been deleted by the storage layer. This event can be cancelled by calling preventDefault() on it. The file will still be deleted, but the files dialog won't be updated.</p><p>Parameters</p><ul><li><code>path</code> The path that was passed to the storage layer.</li><li><code>response</code> The http responseText</li><li><code>message</code> An error message, if error is true</li><li><code>error</code> Boolean. True if an error occured. The error message is in message.</li></ul>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-stash",
"contents": [
{
"text": "<p>Fires on the <code>document</code> before SimplyEdit starts to collect the data for the storage layer and thus before the data is saved. This event cannot be cancelled. You can use this event to do some data manipulation before the data is saved. Especially useful if you have created data sources that have the <code>editor.currentData</code> as their source.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-stashed",
"contents": [
{
"text": "<p>Fires on the <code>document</code> after SimplyEdit has collected all the data for the storage layer. This data is now also available in <code>localStorage.data</code>. You could now revert any changes made in the <code>simply-stash</code> event, without affecting the data sent to the storage layer.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-image-save-error",
"contents": [
{
"text": "<p>Fires on the <code>document</code> after trying to save an image using the storage layer has failed. This event can be cancelled by calling <code>event.preventDefault()</code>. This means that SimplyEdit will not show an error message.</p><p>Parameters</p><ul><li><code>path</code> The path of the image</li><li><code>response</code> The response of the storage layer</li><li><code>message</code> The error message</li><li><code>error</code> <code>true</code></li></ul>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-file-save-error",
"contents": [
{
"text": "<p>Fires on the <code>document</code> after trying to save a file using the storage layer has failed. This event can be cancelled by calling <code>event.preventDefault()</code>. This means that SimplyEdit will not show an error message.</p><p>Parameters</p><ul><li><code>path</code> The path of the file</li><li><code>response</code> The response of the storage layer</li><li><code>message</code> The error message</li><li><code>error</code> <code>true</code></li></ul>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-page-save-error",
"contents": [
{
"text": "<p></p><p>Fires on the <code>document</code> after trying to save a page using the storage layer has failed. This event can be cancelled by calling <code>event.preventDefault()</code>. This means that SimplyEdit will not show an error message.</p><p>Parameters</p><ul><li><code>path</code> The path of the page</li><li><code>response</code> The response of the storage layer</li><li><code>message</code> The error message</li><li><code>error</code> <code>true</code></li></ul>",
"data-simply-template": "text"
}
]
},
{
"title": "simply-selectable-inserted",
"contents": [
{
"text": "<p>Fired on the <code>document</code> whenever a new list item is inserted.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "databind:elementresolved",
"contents": [
{
"text": "<p>Fired on a DOM element whenever its contents have been updated to reflect changes elsewhere.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "databind:resolved",
"contents": [
{
"text": "<p>Fired on the <code>document</code> whenever changes to the DOM have been made to reflect changes in the data structure.</p>",
"data-simply-template": "text"
}
]
},
{
"title": "databinding:valuechanged",
"contents": [
{
"text": "<p>An event you can fire to force the databinding to update the data bound to the field or list the event is fired upon. Some DOM changes cannot be detected automatically. This event allows you to still update the databinding in those cases.</p>",
"data-simply-template": "text"
},
{
"code": "field.setAttribute('data-foo','bar');\neditor.fireEvent('databinding:valuechanged',field);",
"data-simply-template": "code"
}
]
},
{
"title": "databinding:pause",
"contents": [
{
"text": "<p>An event you can fire to stop the databinding updates. This can be helpful when you want to change a lot of data at once. By stopping the databinding while you do that, you can greatly increase the performance of the change. Restart the databinding by calling <code>databinding:resume</code>.</p>",
"data-simply-template": "text"
},
{
"code": "var list = document.querySelector('#myList');\neditor.fireEvent('databinding:pause', list);\nvar items = list.querySelectorAll(':scope > [data-simply-list-item]');\nfor (var i=0; i<items.length; i++) {\n list.removeChild(items[i]);\n}\neditor.fireEvent('databinding:resume', list);",
"data-simply-template": "code"
}
]
},
{
"title": "databinding:resume",
"contents": [
{
"text": "<p>An event you can fire to resume the databinding updates. See <code>databinding:pause</code> for more information.</p>",
"data-simply-template": "text"
}
]
}
]
},
{
"title": "Storage",
"topics": [
{
"contents": [
{
"text": "<p>SimplyEdit has support for different storage schemes. By default it will try to autodetect the scheme based on the domain name and the <code>data-simply-endpoint</code> attribute. Out of the box SimplyEdit supports the following storage schemes:</p><ul><li><code>default</code> This assumes SimplyEdit can <code>PUT</code> the <code>data.json</code> file at the specified endpoint, appended with <code>data/data.json</code>.</li><li><code>github</code> This scheme is active on all domains ending on <code>github.io</code> or <code>github.com</code>, or when specified with <code>data-simply-storage=\"github\"</code>.</li><li><code>beaker</code> Active only with <code>data-simply-storage=\"beaker\"</code>.</li><li><code>ariadne</code> Active only with <code>data-simply-storage=\"ariadne\"</code>.</li></ul><p>But besides these, you can write your own storage scheme and plug it into SimplyEdit. Before you do that though, check out if the default storage scheme works for you as-is.</p>",
"data-simply-template": "text"
}
],
"title": "Introduction"
},
{
"contents": [
{
"text": "<p>By default SimplyEdit uses a very simple protocol to store and retrieve the data of the whole site. Retrieval is done by making an HTTP GET request to the data-simply-endpoint appended with data/data.json. This json file should have the following format:</p>",
"data-simply-template": "text"
},
{
"code": "{\n '/': {..},\n '/subdir/': {..}\n}",
"data-simply-template": "code"
},
{
"text": "<p>Each page in a site is represented with a key denoting the absolute path within the sites domain and an object containing all the data for that page. The properties of this page object are defined in the page template, using the data-simply-field and data-simply-list attributes.</p><p>When you press save, SimplyEdit sends a new GET request for the data.json file and checks that it hasn't changed. If it has, SimplyEdit will try to merge the data automatically. But if that fails, SimplyEdit opens a dialog with the differences highlighted and asks the user to perform the merge by hand.</p><p>Then SimplyEdit sends a PUT request to the exact same location. The contents of the body contain the complete data.json file.</p><p>You can just write your own server-side code to handle this flow and store the contents of the data.json file however you like. You don't have to include all the sites data in the data.json either, just those parts that are needed to render the current page. However, SimplyEdit will only save what you send it in the first place, so if you go this route, it is your responsibility to retrieve and store the correct parts.</p>",
"data-simply-template": "text"
}
],
"title": "The Default Storage"
},
{
"title": "Custom Storage",
"contents": [
{
"text": "<p>When the default storage schemes aren't sufficient, you can just write your own and plug it into SimplyEdit. For example this storage scheme stores all content in localStorage:</p>",
"data-simply-template": "text"
},
{
"code": "var myCustomStorage = {\n init : function(endpoint) {\n this.endpoint = endpoint;\n },\n save : function(data, callback) {\n localStorage.simplyData = data;\n callback();\n },\n load : function(callback) {\n if (!localStorage.simplyData) {\n localStorage.simplyData = \"{}\";\n }\n callback(localStorage.simplyData);\n },\n connect : function() {\n return true;\n },\n disconnect : function() {\n return true;\n }\n};",
"data-simply-template": "code"
},
{
"data-simply-template": "text",
"text": "<p>Then you must tell SimplyEdit to use this storage scheme:</p>"
},
{
"data-simply-template": "code",
"code": "<script src=\"//cdn.simplyedit.io/1/simply-edit.js\"\n data-simply-storage=\"customStorage\"\n></script>"
},
{
"data-simply-template": "text",
"text": "<p>Any storage plugin must include the following methods:</p><ul><li><code>init</code> Called when first initializing the storage scheme with the given endpoint.</li><li><code>save</code> Called when the user presses save.</li><li><code>load</code> Called after initializing and before each save.</li></ul><p>It may also include these methods:</p><ul><li><code>connect</code> Called after init and before load. This allows you to show a login prompt for example.</li><li><code>disconnect</code> Called after pressing logout. This allows you to clean up cookies for example.</li><li><code>list</code> Called whenever a file or image browse dialog is updated. List is called with an endpoint URL and a callback method. It should call the callback method with an object containing three arrays: folders, files and images:</li></ul>"
},
{
"code": "{\n folders : [\n {\n url : \"http://endpoint.com/folder1/\",\n name : \"Folder 1\"\n }\n ],\n files : [\n {\n url : \"http://endpoint.com/myfile.txt\",\n name : \"myfile.txt\"\n }\n ],\n images : [\n {\n url : \"http://endpoint.com/image1.png\",\n name : \"image1.png\"\n }\n ]\n}",
"data-simply-template": "code"
}
]
}
]
},
{
"title": "Custom Fields",
"topics": [
{
"contents": [
{
"data-simply-template": "text",
"text": "<p>For anything to be editable in SimplyEdit, it has to be defined as a 'field'. SimplyEdit comes with a list of predefined field types, like most INPUT elements, IMG, A, and a generic field type for all other HTML elements.</p><p>A field type defines how content is set and how it is retrieved. It defines a selector that tells SimplyEdit how to recognize the field type, and it defines the behaviour when SimplyEdit is turned on - or switched to editing mode.</p><p>If you want to override the default behaviour for a specific type of content, the best way is to create your own custom field type.</p>"
}
],
"title": "Introduction"
},
{
"contents": [
{
"data-simply-template": "text",
"text": "<p>To register a new field type you need 4 things:</p><ul><li>a selector</li><li>a getter function</li><li>a setter function</li><li>an <code style=\"font-weight: normal;\">editable</code> function</li></ul>"
},
{
"data-simply-template": "code",
"code": "editor.field.registerType(\n '[data-readonly]', // selector\n function(field) { // getter\n return field.innerHTML;\n },\n function(field, data) { // setter\n field.innerHTML = data.innerHTML ? data.innerHTML: data;\n },\n function() { // make editable\n // do nothing, this item is readonly\n }\n);"
},
{
"data-simply-template": "text",
"text": "<p>Any element in the browsers DOM can be turned into a field. Like the example above, it doesn't have to be editable. Aas long as you can get and set its values, you can use it with SimplyEdit's databinding. </p><p>Note that SimplyEdit has default methods you can re-use to make your custom field work more like the default fields in SimplyEdit. You can use these as follows:</p>"
},
{
"data-simply-template": "code",
"code": "editor.field.registerType(\n '[data-readonly]', // selector\n function(field) { // getter\n return editor.field.defaultGetter(field, [\"innerHTML\"]);\n },\n function(field, data) { // setter\n editor.field.defaultSetter(field, data);\n },\n function() { // make editable\n // do nothing, this item is readonly\n }\n);"
},
{
"data-simply-template": "text",
"text": "<p>Or you can just redefine the parts you want to change:</p>"
},
{
"data-simply-template": "code",
"code": "editor.field.registerType(\n '[data-readonly]',\n null,\n null,\n function() {\n }\n);"
},
{
"data-simply-template": "text",
"text": "<p>Note: make sure that the data returned by your getter has the exact same format as the data parameter in your setter! If you don't SimplyEdit won't be able to keep your data and the DOM element in sync, but it will keep trying...</p>"
}
],
"title": "Register a custom field type"
}
]
}
],
"search-results-count": "",
"search-results": []
},
"/simplyview/": {
"meta title": "Reference",
"chapters": [
{
"title": "Introduction",
"topics": [
{
"contents": [
{
"text": "<p>SimplyView is a set of seperate components that allow you to rapidly build web application user interfaces. They are designed to work with modern reactive libraries, like that included in SimplyEdit.</p><p>SimplyView seperates structure - HTML - from behaviour - javascript. There is never a need to write HTML inside your javascript code. There is also never a need to write javascript - or any other kind of code- inside your HTML. This strict seperation allows for a much easier workflow between designers and developers.</p><p>This seperation also makes it possible, even easy, to re-use and upgrade existing web applications. There is no need to rewrite everthing from scratch. SimplyView works well with jQuery. In rare cases you can use the <code>simply.activate</code> component to make sure your legacy javascript can react to changes in the HTML structure.</p>",
"data-simply-template": "text"
}
],
"title": "Basic Concepts"
}
]
},
{
"title": "simply.app",
"topics": [
{
"contents": [
{
"data-simply-template": "text",
"text": "<p>simply.app provides a simple starting point to build web applications:<br></p>"
},
{
"data-simply-template": "code",
"code": "<p>var myApp = simply.app({\n routes: {</p><p> '/:section/': function(params) { ... }\n },</p><p> commands: { ... },</p><p> actions: { ... },</p><p> container: document.getElementById('myApp'),</p><p> view: {\n myVariable: 'foo'</p><p> }</p><p>});</p>"
},
{
"data-simply-template": "text",
"text": "<p>It combines simply.route, simply.command, simply.action and simply.view into a single application wrapper.</p>"
}
],
"title": "Overview"
}
]
},
{
"topics": [
{
"contents": [
{
"data-simply-template": "text",
"text": "<p>simply.view provides a simple interface to use the databinding from SimplyEdit in a web application:<br></p>"
},
{
"data-simply-template": "code",
"code": "<p>var myView = {</p><p> foo: 'bar'\n};</p><p>simply.view(myApp, myView);</p>"
},
{
"data-simply-template": "text",
"text": "<p>But generally you won't use this directly, but through simply.app:</p>"
},
{
"data-simply-template": "code",
"code": "<p>var counterApp = simply.app({\n view: {\n counter: 1</p><p> }</p><p>});</p>"
},
{
"data-simply-template": "text",
"text": "<p>Any <code>data-simply-field</code> you define in your apps HTML is automatically bound to the corresponding entry in the view.<br></p>"
}