Append &fields=field1,field2,field3 to the query, substituting the desired field names for "field1," etc.
51 |
52 |
Methods
53 |
54 |
Dictionary
55 |
56 |
When provided with a term, returns all definitions for that term found within the code. Optionally, when provided with a section identifier and no term, returns all terms that apply within the scope of that section.
Pass the parameter section and a section number, and get only the definition of the term that is relevant to that law. (Most terms have a defined scope of a given structural unit or law.) N.B.: Because only one definition is returned, rather than providing an array of definitions, just a single definition’s fields are returned. They are not stored as the lone element in an array, but are at the top level of the JSON.
This is based on the structural unit labels, which vary between implementations. Possible values might be title, chapter, part, or others. A definition that applies to just one law would have a value of section, while a definition that applies to the whole code would have a value of global.
125 |
126 |
127 |
128 |
section_number
129 |
string
130 |
The unique identifier for the section in which the definition appears.
131 |
132 |
133 |
134 |
135 |
url
136 |
string
137 |
The URL of the section in which the definition appears.
138 |
139 |
140 |
141 |
142 |
formatted
143 |
string
144 |
The definition, with display-ready formatting and a citation.
145 |
This is the same as the content of definition, with typographic niceties and a parenthetical citation.
146 |
147 |
148 |
149 |
generic
150 |
boolean
151 |
Determines if the query should include terms from the generic dictionary.
Internal unique identifier for the law's containing structural unit.
287 |
288 |
289 |
290 |
291 |
catch_line
292 |
string or null
293 |
The title of this section.
294 |
Not all legal codes have catch lines. California's laws, for instance, lack them.
295 |
296 |
297 |
298 |
history
299 |
string or null
300 |
The acts of the legislature that created this law.
301 |
Only some legal codes include histories.
302 |
303 |
304 |
305 |
full_text
306 |
string
307 |
The complete text of the law as a single string of text.
308 |
This duplicates the collective contents of `text`, but concatenates all subsections into a single string.
309 |
310 |
311 |
312 |
repealed
313 |
true/false
314 |
Indicates whether this law is still in force.
315 |
Only some legal codes continue to publish laws that have been repealed.
316 |
317 |
318 |
319 |
text
320 |
array
321 |
Contains the subsections of text that comprise this law.
322 |
There is one child element for each subsection. Some codes may be broken up not by labelled subsection, but by paragraphs that lack any labels or unique identifiers.
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
text
331 |
string
332 |
The text of the subsection.
333 |
334 |
335 |
336 |
type
337 |
string
338 |
What type of subsection this is—`section` (the default), `table`, `illustration`, or possibly others, as dictated by the needs of each legal code.
339 |
340 |
341 |
342 |
prefixes
343 |
array
344 |
A list of of the complete prefix path that uniquely identifies this subsection.
345 |
346 |
347 |
348 |
prefix
349 |
string or null
350 |
This subsection's identifying prefix.
351 |
352 |
353 |
354 |
entire_prefix
355 |
string or null
356 |
The complete, uniquely identifying prefix for this subsection.
357 |
The same data that's in `prefixes`, only collapsed into a single string.
358 |
359 |
360 |
prefix_anchor
361 |
string or null
362 |
The complete, uniquely identifying prefix for this subsection, ready to be used in a URL.
363 |
This is `entire_prefix`, URL encoded.
364 |
365 |
366 |
level
367 |
integer
368 |
How deeply nested that this level is, in the hierarchy of subsections. 1 is the top level.
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
ancestry
378 |
array
379 |
Contains a subsection for each hierarchically nested structural unit that contains this law.
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
id
390 |
integer
391 |
Internal unique identifier for this structural unit.
392 |
393 |
394 |
395 |
name
396 |
string
397 |
The title of this structural unit.
398 |
399 |
400 |
401 |
identifier
402 |
string
403 |
The identifer for this structural unit.
404 |
This will often—but not always—be a number.
405 |
406 |
407 |
label
408 |
string
409 |
The name of this level of structural unit.
410 |
411 |
412 |
413 |
url
414 |
string
415 |
The public (non-API) URL for this structural unit.
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
structure_contents
426 |
array
427 |
Contains a subsection for each law that is part of the immediate structural unit (siblings of the requested section).
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
id
438 |
integer
439 |
Internal unique identifier for this law.
440 |
441 |
442 |
443 |
444 |
structure_id
445 |
integer
446 |
Internal unique identifier for the containing structural unit.
447 |
448 |
449 |
450 |
451 |
section_number
452 |
string
453 |
The unique identifier for this section.
454 |
455 |
456 |
457 |
458 |
catch_line
459 |
string or null
460 |
The title of this section.
461 |
Not all legal codes have catch lines. California's laws, for instance, lack them.
462 |
463 |
464 |
465 |
url
466 |
string
467 |
The public (non-API) URL for this law.
468 |
469 |
470 |
471 |
472 |
api_url
473 |
string
474 |
The API URL for this law.
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
previous_section
485 |
array
486 |
The prior law within the containing structural unit, as ordered.
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
id
497 |
integer
498 |
Internal unique identifier for this law.
499 |
500 |
501 |
502 |
503 |
structure_id
504 |
integer
505 |
Internal unique identifier for the containing structural unit.
506 |
507 |
508 |
509 |
510 |
section_number
511 |
string
512 |
The unique identifier for this section.
513 |
514 |
515 |
516 |
517 |
catch_line
518 |
string or null
519 |
The title of this section.
520 |
Not all legal codes have catch lines. California's laws, for instance, lack them.
521 |
522 |
523 |
524 |
url
525 |
string
526 |
The public (non-API) URL for this law.
527 |
528 |
529 |
530 |
531 |
api_url
532 |
string
533 |
The API URL for this law.
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
next_section
544 |
array
545 |
The following law within the containing structural unit, as ordered.
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
id
556 |
integer
557 |
Internal unique identifier for this law.
558 |
559 |
560 |
561 |
562 |
structure_id
563 |
integer
564 |
Internal unique identifier for the containing structural unit.
565 |
566 |
567 |
568 |
569 |
section_number
570 |
string
571 |
The unique identifier for this section.
572 |
573 |
574 |
575 |
576 |
catch_line
577 |
string or null
578 |
The title of this section.
579 |
Not all legal codes have catch lines. California's laws, for instance, lack them.
580 |
581 |
582 |
583 |
url
584 |
string
585 |
The public (non-API) URL for this law.
586 |
587 |
588 |
589 |
590 |
api_url
591 |
string
592 |
The API URL for this law.
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
metadata
603 |
array, or null
604 |
Contains all metadata about this law that is stored separately in the metadata table.
605 |
By default, this contains nothing, but any State Decoded implementation that wants to store additional metadata about laws—data beyond the structure otherwise described here—would emit that metadata here.
606 |
607 |
608 |
609 |
court_decisions
610 |
array, or null
611 |
Every court decision that cites this law.
612 |
Only available within State Decoded implementations that have chosen to ingest court rulings.
613 |
614 |
615 |
616 |
official_url
617 |
string, or null
618 |
The URL for this law on the official website for this legal code.
619 |
620 |
621 |
622 |
623 |
history_text
624 |
string, or null
625 |
A narrative version of the history field.
626 |
627 |
628 |
629 |
630 |
references
631 |
array
632 |
A listing of all other laws that refer to this one.
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
id
643 |
integer
644 |
Internal unique identifier for this law.
645 |
646 |
647 |
648 |
649 |
section_number
650 |
string
651 |
The unique identifier for this section.
652 |
653 |
654 |
655 |
656 |
catch_line
657 |
string or null
658 |
The title of this section.
659 |
Not all legal codes have catch lines. California's laws, for instance, lack them.
660 |
661 |
662 |
663 |
url
664 |
string
665 |
The public (non-API) URL for this law.
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
related
676 |
array
677 |
A list of all other laws that are have been determined through lexical analysis to be similar to this one.
782 | {
783 | "section_number": "15.2-627",
784 | "section_id": "7508",
785 | "structure_id": "1980",
786 | "catch_line": "Department of education.",
787 | "history": "Code 1950, § 15-324; 1956, c. 153; 1962, c. 623, § 15.1-644; 1980, c. 559; 1981, c. 246; 1982, cc. 32, 75; 1995, c. 8; 1996, c. 873; 1997, c. 587.",
788 | "full_text": "<p>The department of education shall consist of the county school board, the division superintendent of schools and the officers and employees thereof. Except as herein otherwise provided, the county school board and the division superintendent of schools shall exercise all the powers conferred and perform all the duties imposed upon them by general law. Except for the initial elected board which shall consist of five members, the county school board shall be composed of not less than three nor more than nine members; however, there shall be at least one school board member elected from each of the county’s magisterial or election districts. The members shall be elected by popular vote from election districts coterminous with the election districts for the board of county supervisors. The exact number of members shall be determined by the board of county supervisors. Elections of school board members shall be held to coincide with the elections of members of the board of county supervisors at the regular general election in November. The terms of office for the county school board members shall be the same as the terms of the members of the board of county supervisors and shall commence on January 1 following their election.<\/p><p>A vacancy in the office of school board member shall be filled pursuant to §§ 24.2-226 and 24.2-228.<\/p><p>In order to have their names placed on the ballot, all candidates shall be nominated only by petition as provided by general law pursuant to § 24.2-506.<\/p><p>The county school board may also appoint a resident of the county to cast the deciding vote in case of a tie vote of the school board as provided in § 22.1-75. The tie breaker, if any, shall be appointed for a four-year term whether appointed to fill a vacancy caused by expiration of term or otherwise.<\/p><p>The chairman of the county school board, for the purpose of appearing before the board of county supervisors, shall be considered head of this department, unless some other person in the department shall be designated by the school board for such purpose.<\/p>",
789 | "repealed": "n",
790 | "text": {
791 | "0": {
792 | "text": "The department of education shall consist of the county school board, the division superintendent of schools and the officers and employees thereof. Except as herein otherwise provided, the county school board and the division superintendent of schools shall exercise all the powers conferred and perform all the duties imposed upon them by general law. Except for the initial elected board which shall consist of five members, the county school board shall be composed of not less than three nor more than nine members; however, there shall be at least one school board member elected from each of the county’s magisterial or election districts. The members shall be elected by popular vote from election districts coterminous with the election districts for the board of county supervisors. The exact number of members shall be determined by the board of county supervisors. Elections of school board members shall be held to coincide with the elections of members of the board of county supervisors at the regular general election in November. The terms of office for the county school board members shall be the same as the terms of the members of the board of county supervisors and shall commence on January 1 following their election.",
793 | "type": "section",
794 | "prefixes": [
795 | ""
796 | ],
797 | "prefix": "",
798 | "entire_prefix": "",
799 | "prefix_anchor": "",
800 | "level": 1
801 | },
802 | "1": {
803 | "text": "A vacancy in the office of school board member shall be filled pursuant to §§ 24.2-226 and 24.2-228.",
804 | "type": "section",
805 | "prefixes": [
806 | ""
807 | ],
808 | "prefix": "",
809 | "entire_prefix": "",
810 | "prefix_anchor": "",
811 | "level": 1
812 | },
813 | "2": {
814 | "text": "In order to have their names placed on the ballot, all candidates shall be nominated only by petition as provided by general law pursuant to § 24.2-506.",
815 | "type": "section",
816 | "prefixes": [
817 | ""
818 | ],
819 | "prefix": "",
820 | "entire_prefix": "",
821 | "prefix_anchor": "",
822 | "level": 1
823 | },
824 | "3": {
825 | "text": "The county school board may also appoint a resident of the county to cast the deciding vote in case of a tie vote of the school board as provided in § 22.1-75. The tie breaker, if any, shall be appointed for a four-year term whether appointed to fill a vacancy caused by expiration of term or otherwise.",
826 | "type": "section",
827 | "prefixes": [
828 | ""
829 | ],
830 | "prefix": "",
831 | "entire_prefix": "",
832 | "prefix_anchor": "",
833 | "level": 1
834 | },
835 | "4": {
836 | "text": "The chairman of the county school board, for the purpose of appearing before the board of county supervisors, shall be considered head of this department, unless some other person in the department shall be designated by the school board for such purpose.",
837 | "type": "section",
838 | "prefixes": [
839 | ""
840 | ],
841 | "prefix": "",
842 | "entire_prefix": "",
843 | "prefix_anchor": "",
844 | "level": 1
845 | }
846 | },
847 | "ancestry": {
848 | "1": {
849 | "id": "1980",
850 | "name": "County Manager Form of Government",
851 | "identifier": "6",
852 | "label": "chapter",
853 | "url": "/15.2/6/"
854 | },
855 | "2": {
856 | "id": "27",
857 | "name": "Counties, Cities and Towns",
858 | "identifier": "15.2",
859 | "label": "title",
860 | "url": "/15.2/"
861 | }
862 | },
863 | "structure_contents": {
864 | "0": {
865 | "id": "7481",
866 | "structure_id": "1980",
867 | "section_number": "15.2-600",
868 | "catch_line": "Designation of form; applicability of chapter.",
869 | "url": "http://vacode.org/15.2-600/",
870 | "api_url": "http://vacode.org/api/law/15.2-600/"
871 | },
872 | "1": {
873 | "id": "7482",
874 | "structure_id": "1980",
875 | "section_number": "15.2-601",
876 | "catch_line": "Adoption of county manager form.",
877 | "url": "http://vacode.org/15.2-601/",
878 | "api_url": "http://vacode.org/api/law/15.2-601/"
879 | },
880 | "2": {
881 | "id": "7483",
882 | "structure_id": "1980",
883 | "section_number": "15.2-602",
884 | "catch_line": "Powers vested in board of supervisors; election and terms of members; vacancies.",
885 | "url": "http://vacode.org/15.2-602/",
886 | "api_url": "http://vacode.org/api/law/15.2-602/"
887 | },
888 | "3": {
889 | "id": "7484",
890 | "structure_id": "1980",
891 | "section_number": "15.2-603",
892 | "catch_line": "Referendum on election of supervisors by districts or at large.",
893 | "url": "http://vacode.org/15.2-603/",
894 | "api_url": "http://vacode.org/api/law/15.2-603/"
895 | },
896 | "4": {
897 | "id": "7485",
898 | "structure_id": "1980",
899 | "section_number": "15.2-604",
900 | "catch_line": "General powers of board.",
901 | "url": "http://vacode.org/15.2-604/",
902 | "api_url": "http://vacode.org/api/law/15.2-604/"
903 | },
904 | "5": {
905 | "id": "7486",
906 | "structure_id": "1980",
907 | "section_number": "15.2-605",
908 | "catch_line": "Prohibiting misdemeanors and providing penalties.",
909 | "url": "http://vacode.org/15.2-605/",
910 | "api_url": "http://vacode.org/api/law/15.2-605/"
911 | },
912 | "6": {
913 | "id": "7487",
914 | "structure_id": "1980",
915 | "section_number": "15.2-606",
916 | "catch_line": "Investigation of county officers.",
917 | "url": "http://vacode.org/15.2-606/",
918 | "api_url": "http://vacode.org/api/law/15.2-606/"
919 | },
920 | "7": {
921 | "id": "7488",
922 | "structure_id": "1980",
923 | "section_number": "15.2-607",
924 | "catch_line": "Organization of departments.",
925 | "url": "http://vacode.org/15.2-607/",
926 | "api_url": "http://vacode.org/api/law/15.2-607/"
927 | },
928 | "8": {
929 | "id": "7489",
930 | "structure_id": "1980",
931 | "section_number": "15.2-608",
932 | "catch_line": "Designation of officers to perform certain duties.",
933 | "url": "http://vacode.org/15.2-608/",
934 | "api_url": "http://vacode.org/api/law/15.2-608/"
935 | },
936 | "9": {
937 | "id": "7490",
938 | "structure_id": "1980",
939 | "section_number": "15.2-609",
940 | "catch_line": "Appointment of county manager.",
941 | "url": "http://vacode.org/15.2-609/",
942 | "api_url": "http://vacode.org/api/law/15.2-609/"
943 | },
944 | "10": {
945 | "id": "7491",
946 | "structure_id": "1980",
947 | "section_number": "15.2-610",
948 | "catch_line": "Tenure of office; removal.",
949 | "url": "http://vacode.org/15.2-610/",
950 | "api_url": "http://vacode.org/api/law/15.2-610/"
951 | },
952 | "11": {
953 | "id": "7492",
954 | "structure_id": "1980",
955 | "section_number": "15.2-611",
956 | "catch_line": "Disability of county manager.",
957 | "url": "http://vacode.org/15.2-611/",
958 | "api_url": "http://vacode.org/api/law/15.2-611/"
959 | },
960 | "12": {
961 | "id": "7493",
962 | "structure_id": "1980",
963 | "section_number": "15.2-612",
964 | "catch_line": "Manager responsible for administration of affairs of county; appointment of officers and employees.",
965 | "url": "http://vacode.org/15.2-612/",
966 | "api_url": "http://vacode.org/api/law/15.2-612/"
967 | }
968 | },
969 | "previous_section": {
970 | "id": "7507",
971 | "structure_id": "1980",
972 | "section_number": "15.2-626",
973 | "catch_line": "Department and board of social services.",
974 | "url": "http://vacode.org/15.2-626/",
975 | "api_url": "http://vacode.org/api/law/15.2-626/"
976 | },
977 | "next_section": {
978 | "id": "7509",
979 | "structure_id": "1980",
980 | "section_number": "15.2-628",
981 | "catch_line": "Terms of school boards.",
982 | "url": "http://vacode.org/15.2-628/",
983 | "api_url": "http://vacode.org/api/law/15.2-628/"
984 | },
985 | "metadata": {
986 | "history": {
987 | "1": {
988 | "year": "1956",
989 | "chapter": "153"
990 | },
991 | "2": {
992 | "year": "1962",
993 | "chapter": "623",
994 | "section": "1962, c. 623, § 15.1-644"
995 | },
996 | "3": {
997 | "year": "1980",
998 | "chapter": "559"
999 | },
1000 | "4": {
1001 | "year": "1981",
1002 | "chapter": "246"
1003 | },
1004 | "5": {
1005 | "year": "1982",
1006 | "chapter": [
1007 | "32",
1008 | "75"
1009 | ]
1010 | },
1011 | "6": {
1012 | "year": "1995",
1013 | "chapter": "8"
1014 | },
1015 | "7": {
1016 | "year": "1996",
1017 | "chapter": "873"
1018 | },
1019 | "8": {
1020 | "year": "1997",
1021 | "chapter": "587"
1022 | }
1023 | }
1024 | },
1025 | "court_decisions": false,
1026 | "official_url": "http://lis.virginia.gov/cgi-bin/legp604.exe?000+cod+15.2-627",
1027 | "history_text": "This law has been modified 7 times since it was first created in 1956. Those modifications are cataloged by “The Acts of Assembly,” a state publication, by year and chapter. Those modifications that can be read on the General Assembly’s website will be linked accordingly. Those modifications are as follows: in 1962, chapter 623; in 1980, chapter 559; in 1981, chapter 246; in 1982, chapters 32, 75; in 1995 chapter <a href=\"http://leg1.state.va.us/cgi-bin/legp504.exe?951+ful+CHAP0008\">8<\/a>; in 1996 chapter <a href=\"http://leg1.state.va.us/cgi-bin/legp504.exe?961+ful+CHAP0873\">873<\/a>; in 1997 chapter <a href=\"http://leg1.state.va.us/cgi-bin/legp504.exe?971+ful+CHAP0587\">587<\/a>.",
1028 | "references": [
1029 | {
1030 | "id": "12528",
1031 | "section_number": "22.1-29.1",
1032 | "catch_line": "Public hearing before appointment of school board members.",
1033 | "url": "http://vacode.org/22.1-29.1/"
1034 | },
1035 | {
1036 | "id": "12533",
1037 | "section_number": "22.1-34",
1038 | "catch_line": "Application of article.",
1039 | "url": "http://vacode.org/22.1-34/"
1040 | },
1041 | {
1042 | "id": "12542",
1043 | "section_number": "22.1-41",
1044 | "catch_line": "Application of article.",
1045 | "url": "http://vacode.org/22.1-41/"
1046 | },
1047 | {
1048 | "id": "12596",
1049 | "section_number": "22.1-75",
1050 | "catch_line": "Procedure in case of tie vote.",
1051 | "url": "http://vacode.org/22.1-75/"
1052 | }
1053 | ],
1054 | "related": {
1055 | "0": {
1056 | "id": "7469",
1057 | "catch_line": "Department of education.",
1058 | "section_number": "15.2-531",
1059 | "url": "/15.2-531/"
1060 | },
1061 | "1": {
1062 | "id": "7618",
1063 | "catch_line": "Department of education.",
1064 | "section_number": "15.2-837",
1065 | "url": "/15.2-837/"
1066 | },
1067 | "2": {
1068 | "id": "12566",
1069 | "catch_line": "Election of school board members; appointment of tie breaker.",
1070 | "section_number": "22.1-57.3",
1071 | "url": "/22.1-57.3/"
1072 | },
1073 | "3": {
1074 | "id": "7428",
1075 | "catch_line": "County school board and division superintendent of schools.",
1076 | "section_number": "15.2-410",
1077 | "url": "/15.2-410/"
1078 | },
1079 | "4": {
1080 | "id": "7583",
1081 | "catch_line": "Powers of county vested in board of supervisors; membership, election, terms, etc., of board; vacancies; powers of chairman.",
1082 | "section_number": "15.2-802",
1083 | "url": "/15.2-802/"
1084 | }
1085 | },
1086 | "amendment_years": {
1087 | "0": "1950",
1088 | "1": "1956",
1089 | "2": "1962",
1090 | "3": "1980",
1091 | "4": "1981",
1092 | "5": "1982",
1093 | "6": "1995",
1094 | "7": "1996",
1095 | "8": "1997"
1096 | },
1097 | "url": "http://vacode.org/15.2-627/",
1098 | "citation": {
1099 | "official": "Va. Code § 15.2-627",
1100 | "universal": "VA Code § 15.2-627"
1101 | },
1102 | "api_version": "1.0"
1103 | }
1104 |
1105 |
1106 |
Structure
1107 |
1108 |
When provided with a structural identifier identifying an individual structural unit (e.g., a title, a chapter, a part, etc.), returns everything that The State Decoded knows about that structural unit.
Leave [identifier] blank to get a top-level listing of structural units—that is, the major structural units that make up the basic divisions of the code (e.g., titles).
1115 |
1116 |
Optional parameters
1117 |
1118 |
Callback
1119 |
1120 |
Pass the parameter callback and a callback string to have results returned as JSONP.
Pass the parameter detailed and either true or false to indicate whether you want brief results or detailed results. Detailed results are exactly the same as if you'd used the Law method for each result. The standard fields returned by the Search method are all replaced with the standard fields returned by the Law method, with the exception of the score field, which remains.
1475 |
1476 |
Callback
1477 |
1478 |
Pass the parameter callback and a callback string to have results returned as JSONP.
1593 | {
1594 | "results": {
1595 | "section_number": "1-230",
1596 | "catch_line": "Person.",
1597 | "excerpt": "“Person” includes any individual, corporation, partnership, association, cooperative, limited liability company.....",
1598 | "text": "“Person” includes any individual, corporation, partnership, association, cooperative, limited liability company, trust, joint venture, government, political subdivision, or any other legal or commercial entity and any successor, representative, agent, agency, or instrumentality thereof.",
1599 | "url": "http://vacode.org/1-230/",
1600 | "score": "5.6"
1601 | },
1602 | "total_records": "2,263",
1603 | "api_version": "1.0",
1604 | "ancestry": {
1605 | "title": "General Provisions",
1606 | "chapter": "Common Law and Rules of Construction"
1607 | }
1608 | }
1609 |
1610 |
1611 |
1612 |
Suggest
1613 |
1614 |
When provided with a term, or a portion thereof, returns a list of suggestions for how to complete that term, sorted by likelihood of usefulness, limited to 5 results. Intended to be used internally, within the site, as real-time suggestions while typing in search parameters.
When a request cannot be completed, the API will return a JSON-formatted error. For example, if an invalid key is provided in a request, the response would be as follows:
State Decoded comes with a command line tool, statedecoded. This
43 | tool provides a non-web method to perform common actions, such as importing data
44 | and managing editions.
45 |
46 |
Note: to use this tool, the PHP CLI will need to be
47 | installed. (This is installed by default on most systems that have PHP.) On
48 | linux/unix systems, the tool should be set to be executable to be able to run it
49 | directly, but it may also be run as a normal PHP script (php statedecoded
50 | arguments); the examples below assume it is being run as a
51 | standalone executable. Due to path resolution, you'll probably need to run it
52 | with the path prefix as well – if you're in the root of the statedecoded
53 | directory, it will be ./statedecoded.
54 |
55 |
All commands are run with the statedecoded command. You can run
56 | statedecoded help to see all available commands, and you can use
57 | statedecoded help command to see an explanation of a
58 | specific command along with all available options for it.
59 |
60 |
Many commands use the -v=# option to change the output
61 | verbosity. Messages are weighted by importance, so a verbosity of 1 will show
62 | all message, up to a maximum of 10 for only important messages. Any number above
63 | 10 should silence most, if not all messages.
64 |
65 |
Import
66 |
67 |
Instead of having to use the admin area of The State Decoded to parse data
68 | files to import legal codes, the command line tool can be run. This is helpful
69 | if the data is provided on a regular basis, allowing the script to be run as
70 | part of a cron job, scheduled task, or similar.
71 |
72 |
The default import command (statedecoded import) will import
73 | data from the files in the directory specified in the config file as
74 | IMPORT_DATA_DIR. You may override this to use a different directory
75 | with the -d=directory option.
76 |
77 |
By default, the data is imported into the current edition. You may specify a
78 | different edition to update with the --edition=slug option
79 | by specifying the edition slug. Note that you cannot create a new edition using
80 | the import command, you must use the
81 | Create Edition command first.
82 |
83 |
You may make the selected edition current by using the --current
84 | option.
85 |
86 |
Clear Metadata
87 |
88 |
You may clear the metadata associated with laws via the
89 | statedecoded clear-metadata command. By default this removes all
90 | metadata associated with laws for all editions. You may specify a specific
91 | edition to clear with the --edition=slug option, and/or
92 | a particular field to clear out with the --field=field
93 | option. For instance, to clear out all court decisions (which is a good thing
94 | to do every few months to remove stale data), you may run the command
95 | statedecoded --field=court_decisions
96 |
97 |
Environment Test
98 |
99 |
You can test whether your environment is setup properly to run The State
100 | Decoded by running the statedecoded test-env command. This test
101 | is also run automatically before attempting to import data. If the environment
102 | is not sufficient, errors will be listed, and the command will return with an
103 | error code of 1.
104 |
105 |
Migrations
106 |
107 |
When writing new code for The State Decoded, you may need to modify the
108 | database - to create tables, modify existing ones, or manipulate data. To do
109 | this in a way that is repeatable without modifying our base database
110 | definitions, we use database migrations.
These are scripts that
111 | describe the changes to the database in a way that can easily be reproduced.
112 |
113 |
Migrate the Database
114 |
115 |
To run all migrations that have not been run yet, use the statedecoded
116 | migrate command. To "roll back" (undo) all of the migrations, use the
117 | statedecoded migrate --down option.
118 |
119 |
Writing Migrations
120 |
121 |
To generate a new database migration file, run the statedecoded
122 | generate-migration command. This command will print out the name of the
123 | newly-generated migration file.
124 |
125 |
Inside of this file, you will find a class with two methods: an
126 | up method for making changes to the database, and a
127 | down method for undoing those changes when rolling back. You
128 | should fill out both methods when creating a migration, if all changes are able
129 | to be undone. In general, MySQL will not let you modify a database table such
130 | that data is truncated, such as when chaning the size of a field or index – so
131 | for those operations you should not provide a down
132 | method.
133 |
134 |
Migrations use standard SQL queries, wrapped by our database wrapper into a
135 | single database transaction. The $this->queue() method is used
136 | to queue up queries, and these must be run by the $this->execute()
137 | method. Please have a look at the existing migration files in the
138 | includes/migrations/ directory for examples.
139 |
140 |
Note:Migrations are run in the order of their file names.
141 | These files are timestamped to avoid collisions. Unlike some other migration
142 | tools, we keep track of which migrations have been run and execute all
143 | migrations that have not been run, so you shouldn't need to worry out-of-order
144 | migrations being lost from merging branches.
145 |
146 |
147 |
Editions
148 |
149 |
You can manipulate editions with several builtin commands.
150 |
151 |
Note: As of now, you cannot make an edition
152 | current with these commands, you must do that at the time you are importing
153 | data. This is due to the complex changes to permalinks that must occur when an
154 | edition is made current.
155 |
156 |
List Editions
157 |
158 |
To get the name of the current edition, you can use the statedecoded
159 | edition command. To get a list of all editions, use the
160 | statedecoded edition list command. For both of these commands, you
161 | may add the -v (verbose) flag to receive all of the data about the
162 | editions as a JSON-formatted string.
163 |
164 |
Create Editions
165 |
166 |
To create a new edition, use the statedecoded edition create
167 | --name=name command. You may optionally specify a slug for the
168 | edition with the --slug=slug flag, otherwise the slug will
169 | be generated based on the name provided. Note that if your name has spaces in
170 | it, you must provide the name in quotes, e.g. statedecoded
171 | edition create --name="My New Edition".
172 |
173 |
Delete Editions
174 |
175 |
You may delete an edition by its slug with the statedecoded edition
176 | delete --slug=slug command.
Don't use the ternary operator (($size > 2) ? 'small' : 'large').
30 |
The results of conditionals should always go within braces, rather than expressed on a single line, e.g.:
31 |
if ($a == TRUE)
32 | {
33 | echo 'true';
34 | }
35 |
Spaces before conditionals (if ($a == TRUE), not if($a == TRUE))
36 |
Boolean terms in all caps (e.g., TRUE).
37 |
Comments as complete sentences, offset like such:
38 |
/*
39 | * Example comment here.
40 | */
41 |
Comments preceded with // indicate temporary, working comments, generally indicating problems.
42 |
If a bit of code is anything short of perfectly obvious, provide a comment explaining it.
43 |
Use echo, not print.
44 |
HTML 5, meaning self-terminating tags (e.g., <br />
45 |
46 |
--------------------------------------------------------------------------------
/config.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Config file
3 | layout: default
4 | ---
5 | # Configuration Options
6 |
7 | ## SITE_TITLE
8 | What is the title of the website?
9 |
10 | ## PLACE_NAME
11 | What is the name of the place that these laws govern?
12 |
13 | ## LAWS_NAME
14 | What does this place call its laws? e.g., `The Kansas Statutes`, `The Code of Virginia`, etc.
15 |
16 | ## SECTION_SYMBOL
17 | What is the prefix that indicates a section? In many states, this is `§`, but in others it might be `s `. This would be formatted as `§ 1.23-45` or `s. 123`.
18 |
19 | ## WEB_ROOT
20 | The path to the contents of the website, e.g. the location of `index.php`.
21 |
22 | ## IMPORT_DATA_DIR
23 | The directory in which the importer can find the laws to be imported.
24 |
25 | ## CUSTOM_FUNCTIONS
26 | The file in the `/includes/` directory that contains functions custom to this installation. By convention, this is named for the place that these laws govern, e.g. `class.Kansas.inc.php`.
27 |
28 | ## THEMES_DIR
29 | The directory in which themes (site design templates) are found.
30 |
31 | ## THEME_NAME
32 | The name of the theme that's in use.
33 |
34 | ## THEME_DIR
35 | The filesystem path to the directory that contains the theme. This defaults to `TEMPATE_DIR/THEME_NAME` (e.g., `/var/www/example.com/themes/StateDecoded2013/`.)
36 |
37 | ## THEME_WEB_PATH
38 | The public URL of the directory that contains the theme (e.g., `http://example.com/themes/StateDecoded2013/`.)
39 |
40 | ## CURRENT_API_VERSION
41 | Define the default version of the API to send requests to, if a version isn't othewise specified.
42 |
43 | ## EDITION_ID
44 | Establish which version of the code that's in effect sitewide. This is the database ID in the `editions` table. (On a new installation, this will always be `1`.)
45 |
46 | ## EDITION_YEAR
47 | Establish which version of the code that's in effect sitewide. This is the label for the present revision. Although the word "year" appears in the title, if setting up a site for a code that is updated more frequently than annually, another terse label will suffice here (e.g., `2015-02-01` or `2014-Q1`). This label will appear in URLs.
48 |
49 | ## INCLUDES_REPEALED
50 | Does this state's code include laws that have been repealed formally, and that are marked as such? This will suppress their display, so that visits don't have to wade through empty, repealed laws. If your legal code isn't full of vast wastelands of long-abandoned chapters, then you can leave this set to `FALSE`.
51 |
52 | ## LONG_LAW_URLS
53 | Should we use short URLs or long URLs for laws? Short URLs are the default (e.g., `http://example.com/12.3-45:67/`), but if laws have non-unique identifiers, then you'll need to use long URLs (e.g. `http://example.com/56/21/12.3-45:67/`), which are URLs that incorporate the hierarchical structures (e.g., laws, titles, parts, etc.) that contain each law.
54 |
55 | ## PDO_DSN
56 | [PHP Data Object's Data Source Name](http://php.net/manual/en/ref.pdo-mysql.connection.php)—tells PHP how to connect to the MySQL database. (Only MySQL will work.) This looks like this:
57 |
58 | ~~~
59 | mysql:dbname=statedecoded;host=localhost;charset=utf8
60 | ~~~
61 |
62 | `dbname` is the name of the database that you created for The State Decoded. `host` is the name of the database server. This will most often be `localhost`—check with your host for details, if that doesn't work. And `charset` must always be `utf8`.
63 |
64 | ## PDO_USERNAME
65 | The database username.
66 |
67 | ## PDO_PASSWORD
68 | The database password.
69 |
70 | ## GLOBAL_DEFINITIONS
71 | Specify the structural identifier ancestry for the unit of the code that contains definitions of terms that are used throughout the code, and thus should have a global scope. Separate each identifier with a comma. If all global definitions are found in Title 15A, Part BD, Chapter 16.2, that would be identified as `15A,BD,16.2`. If all global definitions are found in Article 36, Section 105, that would be identified as `36,105`. This must be the *complete path* to the container for global definitions, and not a standard citation.
72 |
73 | Not all legal codes need this. This only needs to be specified for those legal codes that list globally applicable definitions but that don't specify within the list of definitions that they are globally applicable. For instance, a legal code might set aside a chapter to list all global definitions, and use the first law in the chapter to say "all following laws apply globally," and then have 100 more laws, each containing a single definition. This is a legal code for which this configuration option is necessary.
74 |
75 | ## STRUCTURE
76 | Create a list of the hiearchy of the code, from the top container to the name of an individual law. A legal code's top structural unit might be "titles," and each title might be divided into "chapters," each chapter might be divided into "parts," and each part might be divided into "sections." That would be rendered here as `title,chapter,part,section`.
77 |
78 | ## SECTION_REGEX
79 | Define the regular expression that identifies section references. It is best to do so without using the legal code's symbol (e.g., `§`), since section references are frequently made without its presence. [A growing collection of per-state regular expressions is available](https://github.com/statedecoded/law-identifier)—even if the regular expression that you need isn't found there, you should be able to find something to repurpose.
80 |
81 | ## ERROR_PAGE_DB
82 | The path, relative to the webroot, to an error page to be displayed if the database connection is not available. (Like the fail whale.) Do not begin this path with a slash. If this is undefined, a bare database connection error will be displayed.
83 |
84 | ## EMAIL_ADDRESS
85 | When there is cause for the website to send an e-mail (e.g., API registration), what "From" address should be used?
86 |
87 | ## EMAIL_NAME
88 | When sending e-mail, what name should appear in the "From" field?
89 |
90 | ## RECORD_VIEWS
91 | Record each view of each law in the laws_views table? Doing so provides a corpus of data that can be useful for analysis, data that will be drawn on in future releases of The State Decoded, but that at present is not used for anything. This is done via MySQL's `INSERT DELAYED`, so it will not slow down page rendering time, but it does require a certain amount of system resources and storage.
92 |
93 | ## USE_GENERIC_TERMS
94 | When embedding definitions for legal terms, should the terms in The State Decoded's built-in legal dictionary be included? If this is set to `FALSE`, only the terms defined within this legal code will appear as defined terms. The built-in legal dictionary includes definitions for nearly 500 legal terms that are not generally defined within legal codes. If any of the terms are defined within this legal code, the generic definition will not be displayed, in favor of the legal code’s custom definition.
95 |
96 | ## SEARCH_CONFIG
97 | This indicates whether the data is indexed with Solr or MySQL and, if Solr, specifies how to interact with Solr. Unusually for these configuration options, the value of this is a JSON-encoded array (JSON-encoded because constants cannot contain arrays). Only the `engine` element is necessary if using MySQL, otherwise all additional listed array elements must be completed as specified within the config file.
98 |
99 | ## API_KEY
100 | The site uses its own API extensively, such as to display inline definitions and inline cross-references. That API is stored here, although you don't have to do it—this is populated automatically at the time that the parser is run.
101 |
102 | ## DISQUS_SHORTNAME
103 | If you want to enable [Disqus](http://www.disqus.com/) commenting for every law, register for Disqus, create a new site, and enter the assigned Disqus shortname here.
104 |
105 | ## VARNISH_HOST
106 | If you're running a Varnish server, and you want The State Decoded to automatically purge expired content, provide the URL (including the port number) here.
107 |
108 | ## GOOGLE_ANALYTICS_ID
109 | If you want to track traffic stats with Google Analytics, provide your site's web property ID here.
110 |
111 | ## TYPEKIT_ID
112 | The State Decoded can optionally render the site using several very nice, commercial fonts, calling them from Adobe's [Typekit](https://typekit.com/) service. This requires [paid registration at the "Portfolio" level](https://typekit.com/plans), which costs $4/month. The provided Typekit site ID goes here. See [the "Typekit typefaces" section of the installation guide](http://statedecoded.github.io/documentation/installation.html#typekit-typefaces) for details about where to find that ID.
113 |
114 | ## COURTLISTENER_USERNAME / COURTLISTENER_PASSWORD
115 | * If you want to display court decisions that affect each law using [CourtListener's REST API](https://www.courtlistener.com/api/rest-info/), you must register for an account and enter your username and password here. See the `get_court_decisions()` method in `class.State-sample.inc.php` to actually enable the display of these decisions.
116 |
117 | # Caching
118 | If you are running APC on your web server, note that all of these configuration constants are cached aggressively. You will need to clear APC's cache after making any changes to them, or else those changes will not take effect for hours or days. This can be done in your site’s admin section. (Note that the option is only displayed if you are running APC.)
119 |
--------------------------------------------------------------------------------
/images/bg_hr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statedecoded/documentation/b654b85128f000b9c983843cfb0a9fce1ddfe71b/images/bg_hr.png
--------------------------------------------------------------------------------
/images/blacktocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statedecoded/documentation/b654b85128f000b9c983843cfb0a9fce1ddfe71b/images/blacktocat.png
--------------------------------------------------------------------------------
/images/icon_download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statedecoded/documentation/b654b85128f000b9c983843cfb0a9fce1ddfe71b/images/icon_download.png
--------------------------------------------------------------------------------
/images/sprite_download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statedecoded/documentation/b654b85128f000b9c983843cfb0a9fce1ddfe71b/images/sprite_download.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Documentation by statedecoded
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
Documentation
19 |
Guides to using The State Decoded, whether deploying a site or using the data from one.
Description of the The State Decoded's XML format, which the platform uses as a simple, common format to import legal codes. Also, how to convert other XML formats into The State Decoded's format using provided XSLT.
Instructions about how to configure and tune Solr, the search system that powers aspects of The State Decoded, and suggestions about how to use software other than Solr, such as a hosted search system.
A narrative description of how the parser works, for those who want to modify it to import legal information in a format other than The State Decoded's XML format.
A checklist of steps to be taken before releasing a new version of The State Decoded.
64 |
65 |
66 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installation
3 | layout: default
4 | ---
5 |
6 | # Contents
7 | {:.no_toc}
8 |
9 | * Will be replaced with the ToC, excluding the "Contents" header
10 | {:toc}
11 |
12 | # Requirements
13 |
14 | The following programs and modules are required to run The State Decoded, in addition to a basic LAMP/WAMP stack (MySQL 5+, PHP 5.4+, Apache 2+). *Nearly all of these are almost certainly already installed and configured properly on any standard server.* The exception is on Amazon’s EC2 and other stripped-down cloud servers. The State Decoded’s installer will automatically check to see whether these are installed and running, and alert you to any problems.
15 |
16 | * Make sure that that [`.htaccess` files can use `RewriteRule`](https://help.ubuntu.com/community/EnablingUseOfApacheHtaccessFiles)
17 | * Make sure that [`MultiViews` isn’t enabled](http://httpd.apache.org/docs/2.2/mod/mod_negotiation.html#multiviews) for your site’s virtual host.
18 | * Make sure that [`php.ini` has `allow_url_fopen` enabled](http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen).
19 | * [Make sure that Apache has `mod_rewrite` enabled](http://stackoverflow.com/questions/9021425/how-to-check-if-mod-rewrite-is-enabled-in-php):
20 | * Red Hat/Fedora/CentOS: uncomment [`mod_rewrite.so` from `httpd.conf`](http://www.ewhathow.com/2013/09/how-to-enable-mod_rewrite-on-apache/)
21 | * SuSE: [add `rewrite` to the `APACHE_MODULES` portion of `/etc/sysconfig/apache2`](http://enarion.net/web/htaccess/mod_rewrite-on-suse/)
22 | * Debian/Ubuntu: `sudo a2enmod rewrite`
23 | * Windows: uncomment [`mod_rewrite.so` from `httpd.conf`](http://www.webdevdoor.com/php/mod_rewrite-windows-apache-url-rewriting/)
24 | * Make sure that Apache has `mod_env` enabled:
25 | * Red Hat/Fedora/CentOS/Windows: [instructions](http://serverfault.com/questions/56394/how-do-i-enable-apache-modules-from-the-command-line-in-redhat/56435#56435)
26 | * SuSE: [instructions](http://johannesluderschmidt.de/lang/en-us/django-invalid-command-setenv-in-opensuse/291/)
27 | * Debian/Ubuntu: `sudo a2enmod env`
28 | * Make sure that [PHP's PDO extension](http://php.net/manual/en/book.pdo.php) has MySQL support included, and install `php-curl`, `php-tidy` (or `tidy`), `zip`, and `xmllint`:
29 | * Red Hat/Fedora/CentOS: `sudo yum install php-mysql php-curl php-tidy zip libxml2`
30 | * SuSE: `yast2 --install php5-mysql php5-curl php5-tidy zip libxml2-tools`
31 | * Debian/Ubuntu: `sudo apt-get install php5-mysql php5-curl php5-tidy zip libxml2-utils`
32 | * Windows: `add to php.ini: extension=php_pdo_mysql.dll`
33 |
34 | * (Optional) Solr Search Engine
35 |
36 | Instead of the built-in text search engine, you may use the more advanced Solr search engine. This provides many enhancements over the default engine, but can be difficult to setup and configure.
37 |
38 | * You must use Apache Solr 4.3 or newer.
39 | * In most cases this rules out any system package installations (via `yum`, `yast2`, `apt-get`, etc.), which are all older versions.
40 | * Simply [download Solr](http://lucene.apache.org/solr/downloads.html) to your server, and in the `example/` directory, run `java -jar start.jar -Dsolr.solr.home=/var/www/example.com/solr_home/`, replacing `/var/www/example.com/solr_home/` with the actual path to the `solr_home` directory, which is provided as part of the State Decoded download.
41 | * Note the port number on which Solr is running. This is `8080` by default, but some Linux distributions (e.g., Ubuntu) will set it to `8983` instead. If it isn't `8080`, then you'll need to modify `SOLR_URL` in `config.inc.php` to reflect that different port number.
42 | * When deploying a production site, you'll need to follow [Apache's guide to enabling Solr as a standard system service that will start at boot time](http://wiki.apache.org/solr/SolrJetty#Init_script_to_run_the_Solr_example).
43 | * You'll also need to edit The State Decoded's `config.inc.php` file to use the SolrSearchEngine; an example configuration is provided.
44 |
45 | # Basic configuration
46 |
47 | Here is the process of configuring the beta version of The State Decoded.
48 |
49 | 1. Upload the `htdocs`, `includes`, and `solr_home` directories to your web server (e.g., all within `/var/www/example.com/`), with `htdocs` serving as the web server's document root (e.g. `/var/www/example.com/htdocs/`).
50 | 1. Create a new MySQL database (e.g., `mysqladmin create statedecoded`) and make sure that the web server has access to it.
51 | 1. Rename `config-sample.inc.php` to `config.inc.php`
52 | 1. Rename `class.State-sample.inc.php` to `class.[Placename].inc.php` (e.g., `class.Kansas.inc.php`).
53 | 1. Go through `config.inc.php` and configure each setting. Additional details about each setting can be found within [the configuration file documentation](config.html).
54 | 1. Prepare the parser, selecting from these two methods:
55 | * Straightforward method: With all laws in [the State Decoded XML format](xml-format.html), copy all XML files to `htdocs/admin/import-data/`.
56 | * Custom method: Modify `class.[Statename].inc.php`—specifically `Parser::iterate`, `Parser::parse`, and `Parser::store`—to support the legal code that you will be importing. See “[How the Parser Works](parser.html)” for details.
57 | 1. Load `http://example.com/admin/` in your browser and follow the prompts in the "Import Data" section. Wait while the parser runs, which could require anywhere from 5-60 minutes to run, depending on the power of your server and the length of your legal code. This is iterating through the XML, loading it into the database, and creating the website. When the is parser finished, you have a complete site for your legal code at `http://example.com/`.
58 |
59 | # Advanced configuration
60 |
61 | ## Typekit typefaces
62 |
63 | The State Decoded has been designed to look best with three specific fonts: [FF Meta Serif Web Pro](https://typekit.com/fonts/ff-meta-serif-web-pro), [Adobe Jenson Pro](https://typekit.com/fonts/adobe-jenson-pro), and [Proxima Nova](https://typekit.com/fonts/proxima-nova). In order to use these fonts on the site, it's necessary to [pay for an account on Typekit](https://typekit.com/plans), Adobe's website font service. These three fonts require their "Portfolio" plan, which costs $4/month.
64 |
65 | If you do not sign up for Typekit, the site will work perfectly well. It simply won't look as nice as it otherwise would.
66 |
67 | ## Custom functions
68 |
69 | Within the `State` class, in `class.[Statename].inc.php`, there exist several methods, commented out, that can be written for your specific implementation, to provide additional functionality on your site. To implement these, it is only necessary to write the methods—all of the glue is already in place to include their output within the law object, return the data via the API, and display it on the law pages.
70 |
71 | This class can also be used to house additional functionality not envisioned within The State Decoded.
72 |
73 | ### Official URL
74 |
75 | Method `official_url()`. Turns a law's section number into the URL for the law on its official government website. For example, `10-2.301.4` might become `http://example.gov/laws/10-2.301.4/`. This URL will be provided on the sidebar of every law page and within the API's law method.
76 |
77 | ### Translate history
78 |
79 | Method `translate_history()`. Turns a law's history text into a plain-English version of the same text. For example, `Code 1950, c. 118; 1972, c. 825` might become:
80 |
81 | > This law was first codified in 1950, as recorded in chapter 118 of the Acts of Assembly, and was amended in 1972, by chapter 825.
82 |
83 | The translated history will be displayed after each law on the law page, and will be provided within the API's law method.
84 |
85 | ### Citations
86 |
87 | Method `citations()`. Turns a law's section number and history into one or more citation methods. For example, it might turn a law's section number (10-2.301.4) and the most recent year in which that law was amended (1997) into `Ne. Code § 10-2.301.4 (1997)`. All created citation methods will be displayed in the sidebar of the law page and within the API's law method.
88 |
89 | ## Definition parsing
90 |
91 | Within `class.[Statename].inc.php`, the `extract_definitions()` method does its best to determine the *scope* of definitions. “Scope” is how broadly that a term is to be defined. Some terms are defined only for the purpose of a single law:
92 |
93 | > As used in this section, unless the context requires a different meaning:
94 | >
95 | > “Costs” means the reasonable and customary charges for goods and services incurred or to be incurred in major information technology projects.
96 |
97 | Others might be defined for an entire structural unit—a chapter, title, part, or other named structural unit. And still others might be global, defined for the entire legal code. Every legal code has its own terminology, and many are inconsistent in how a definition's scope is described. "As used in this chapter," "for the purpose of this chapter," and "for purposes of this chapter" are all viable phrases indicating scope. These candidate phrases are stored in the `$scope_indicators` array. The scope of a list of definitions is gathered from the first paragraph in that list.
98 |
99 | Then there are the phrases that indicate an actual definition:
100 |
101 | * "mean"
102 | * "means"
103 | * "shall include"
104 | * "includes"
105 | * "has the same meaning as"
106 | * "shall be construed"
107 | * "shall also be construed to mean"
108 |
109 | These are all terms that can connect a defined term to its definition. These are stored in the `$linking_phrases` array. If your legal code uses different terminology, you need only add its linking phrases to the list.
110 |
111 | Finally, the terms themselves are located based on the presence of quotation marks. (Either straight quotation marks—`U+0022` in Unicode—or angled double quotation marks—`U+201C` and `U+201D` in Unicode.) If the terms within your legal code are not stored within double quotation marks, then `extract_definitions()` will need to be modified to be able to isolate those terms, such as locating them within `` tags. For those rare legal codes that do not offset defined terms in any way (italics, quotation marks, or otherwise; e.g., Nebraska), modifications to the code will be necessary in order to isolate the term being defined.
112 |
113 | The State Decoded does its best to allow for the many terms and phrases employed by different legal codes, but this may need to be tuned to accommodate the legal code that you are parsing. Survey how it indicates the scope of definitions, and how it connects a term to its definition, and modify `extract_definitions()` to suit those circumstances.
114 |
115 | ## Varnish caching
116 |
117 | If you are running a Varnish server, and you want The State Decoded to automatically purge expired content, provide the URL for the Varnish server as the value of `VARNISH_HOST` within `config.inc.php`. Make sure that your [Varnish VCL](https://www.varnish-cache.org/docs/2.1/tutorial/vcl.html) [supports a `BAN`](https://www.varnish-cache.org/docs/3.0/tutorial/purging.html#bans).
118 |
119 | ## Autolinking cross-references
120 |
121 | Many legal codes use coherent, compact, unique citation methods, assigning every law an identifier that is never used elsewhere. With the regular expression in the config file (`SECTION_PCRE`), The State Decoded can identify all cross-references and turn these into links. But for those legal codes that do not use these identifiers, some custom autolinking code will need to be written.
122 |
123 | The first step to doing this is to copy the `replace_sections()` method found within `includes/class.Autolinker.inc.php` and paste it into your `class.[Statename].inc.php` file, within a `State_Autolinker` class, like such:
124 |
125 | ~~~
126 | class State_Autolinker extends Autolinker
127 | {
128 | function replace_sections()
129 | {
130 | [paste method contents here]
131 | }
132 | }
133 | ~~~
134 |
135 | The function of the existing `replace_sections()` method is to process a single match from `SECTION_REGEX`. Normally this is as simple as `return ''.$match.'';`, because the section number is the same as the URL slug. But for something like, say, [the Maryland Code's citations](https://github.com/statedecoded/law-identifier/blob/master/Maryland.md), it's necessary to be able to generate a URL for "§ 9-301 of the State Government Article" (say, `sg-9-301`). That might mean maintaining a lookup table within `replace_sections()` to turn every article name ("State government Article") into a URL prefix ("sg-"). Methods will vary between legal codes.
136 |
--------------------------------------------------------------------------------
/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: An Introduction to The State Decoded
3 | layout: default
4 | ---
5 |
6 | # Contents
7 | {:.no_toc}
8 |
9 | * Will be replaced with the ToC, excluding the "Contents" header
10 | {:toc}
11 |
12 | # What It Does
13 |
14 | The State Decoded is a program that takes structured legal data and generates a website, an API, and bulk downloads based on that legal data. It was designed for U.S. state and municipal legal codes, but it works just as nicely for regulations, contracts, even EULAs. It interfaces with court decisions, legislation, and arbitrary types of connected legal data.
15 |
16 | # Who It’s For
17 |
18 | Governments, open-government groups, lone data hackers, law libraries, or anybody else who wants to put legal data online.
19 |
20 | # How It Works
21 | You provide it with bulk legal data in a simple XML format (or any other format that you might like, if you're comfortable writing PHP), with each XML file storing a single law. After some simple site configuration (editing a config file, maybe making a few tweaks to PHP if you want to customize advanced functionality), you run a parser, which chews through those XML files and uses the data in them to populate a MySQL database. For each law, it stores the text of the law and its relationship to other laws—the chapters etc. into which the laws are divided, and also cross-references between the laws. Then it indexes all of the laws for searching, and exports them in a few different formats for people to download. When the parser is finished, you're left with a complete, wholly functional website for that legal code.
22 |
23 | # Understand the Legal Code
24 |
25 | You'll need to have some level of understanding of how your legal code is structured to be able to import that data into The State Decoded. Most legal codes have a similar organizational system - that is, there are `laws` (usually referred to as `sections`) contained within a hierarchy of `structures` with different labels and names. However, from there, every legal code is different. [This blog post](http://krues8dr.com/blog/2016/08/01/what-i-wish-i-had-known-about-decoding-the-law/) summarizes many of the issues that you may discover in your legal code that will complicate your importing process.
26 |
27 | # Getting a Copy of the Legal Code
28 |
29 | Getting the laws or regulations in question can be a non-trivial challenge. It will almost certainly be more work than actually setting up The State Decoded.
30 |
31 | The best-case scenario is that machine-readable, bulk data is available. This might be XML, JSON, or SGML of the legal code, provided directly by the government in question, or by a vendor on their behalf. This is enormously rare. The worst-case scenario is that the code is available only as printed materials, which would need to be scanned in and OCRed every time that the legal code is updated. The reality is that 95% of the time, the data is available as a middle ground, such as in RTF or Word files, or as HTML.
32 |
33 | It’s quite likely that you’re going to be converting unstructured (or poorly structured) data into structured data. Maybe Word files, maybe screen-scraping HTML. In whatever your language of choice is—any programming language can handle it—you’ll be isolating, extracting, and storing some basic information about each law or regulation: its section number, some sort of structural parent number, an optional catch line or title, and the text of the law. ([See the XML format specification](xml-format.html) for detailed information about these fields.) If possible, develop this on a collaborative platform like GitHub and broadcast to others what you’re doing, because that will allow other people to assist you.
34 |
35 | *Before you screen-scrape any HTML, make sure that you read the website’s terms of service!* If you are prohibited from duplicating the contents of that site, then proceed no further without consulting an attorney.
36 |
37 | The best way to start obtaining bulk legal data is almost always to contact the government in question, after identifying which agency or department is the keeper of the code. It is nearly always best to approach with an open mind, planning to build a relationship with the employees at that education, educate them about what you’re doing and why it’s important, and expect to learn a great deal from them about how the legal code works. (If you aren’t an attorney with deep experience with the legal code in question, you almost certainly do not actually understand how it’s structured, how it’s maintained, or its quirks.) *Do not approach them by citing FOIA or otherwise demanding data with an official-sounding request.* This is often perceived as aggressive, and will not earn you any friends in that government. Be friendly! Talk to them about how you can promote their hard work on the code by making it more widely available, and explore how you can make their job easier. For instance, maybe they’ve been wanting an XML version of their legal code, and the parser you’re building for their Word files could be really helpful to them. These folks are underpaid, their work is underfunded, nobody ever tells them “I’m a big fan of your work.” In all likelihood, *you* are a fan of their work. Say so.
38 |
39 | The worst-case scenario is that you’d need to issue a FOIA request to get the data that you need, and re-issue that request to get an updated copy as often as it’s updated. This is a last resort.
40 |
41 | # You Must Provide Updates
42 |
43 | If you are using The State Decoded for a legal code or for regulations, you must have an ongoing source of updates to those laws to keep your website current. This is an essential element without which you would be foolish to proceed. *It’s not enough to get a copy of the legal code once. You must have a method of obtaining regular updates as the code is updated.* This isn't a technical requirement for the software, but it’s a crucial practical prerequisite.
44 |
45 | # A Stern Warning About Data Quality
46 |
47 | By putting a legal code online, you are providing information that, inevitably, people will rely on. You’re implicitly making an agreement to the public that you will present accurate information and keep that information on your site up-to-date. You mustn’t start a site like this on a lark. You’re making an indefinite commitment to the public interest.
48 |
--------------------------------------------------------------------------------
/javascripts/main.js:
--------------------------------------------------------------------------------
1 | console.log('This would be the main JS file.');
2 |
--------------------------------------------------------------------------------
/javascripts/scale.fix.js:
--------------------------------------------------------------------------------
1 | var metas = document.getElementsByTagName('meta');
2 | var i;
3 | if (navigator.userAgent.match(/iPhone/i)) {
4 | for (i=0; iiterate())
20 | {
21 | $parser->section = $section;
22 | $parser->parse();
23 | $parser->store();
24 | }
25 | ~~~
26 |
27 | `iterate()` retrieves each law, one by one, from the source material, and hands each one of them off to `parse()`. The job of `parse()` is to turn that raw material into a normalized PHP object, which is then passed to `store()`, which puts that data into the database.
28 |
29 | # By Method
30 |
31 | ## iterate()
32 |
33 | The first method to be called, its job is to step through the source of the entirety of the state's laws and extract each law, one at a time. It might be retrieving raw HTML off a web server, stepping through a single XML file on disk, or collecting JSON via an API. Its sole job is to encapsulate the raw material for *just one law* to pass along to `parse()`. This loops over and over again, returning one law with each loop, until finally the entire legal code has been iterated over.
34 |
35 | ## parse()
36 |
37 | The second method to be called, this is where the heavy lifting is done. Its job is to distill each component of a law from the raw material provided by iterate and load it into an object. This might be easy (such as if the data source is well-structured XML or JSON), or might be tricky (such as if the source is HTML or poorly structured XML or JSON). At a minimum this is:
38 |
39 | * name: the "catch line"—the title of the law (e.g. "Proceeds exempt from local taxation")
40 | * text: the complete text of the law
41 | * section_number: the alphanumeric identifier for the law (e.g. "15.2-912.2")
42 | * structure->identifier: the alphanumeric identifier for the law's container—such as chapter or title number (e.g. "16")
43 | * structure->name: the title of the structural container (e.g. "Industrial Development Corporations")
44 |
45 | Optionally, this can be included:
46 |
47 | * history: the legislative history of the law's creation and amendments (e.g. "1995, c. 837, § 18.2-340.32; 1997, cc. 777, 838")
48 |
49 | ## store()
50 |
51 | This method should require minimal customization. The data should have been well massaged within parse(). The one clear exception is the stanza that identifies whether the current law is a list of definitions, generally based on its catch line (e.g., "Definitions," or "Meaning of certain terms"). This list will need to include all catch lines that can indicates that the instant law is a glossary. (See extract_definitions() for more.)
52 |
53 | ## extract_definitions()
54 |
55 | When fed a section that contains a list of definitions, this atomizes them into a list of definitions, and then extracts the term being defined from each definition. Because every state stores these definitions differently (and each state can store them in different ways within the same legal code), this is likely to require some very simple customization.
56 |
57 | The two customizations to be made are to "scope indicators" and to "linking phrases."
58 |
59 | #### Scope indicators
60 |
61 | The first set of phrases to be customized are the scope indicators, stored as `$scope_indicators`. These are the phrases that indicate that a list of definitions is about to follow, and tell the reader what the scope of those definitions is. That is, do these terms apply only within this law? Or they apply to the whole chapter, part, title, article, etc? In context, these phrases might look like this:
62 |
63 | > The following terms are to be defined as such when used in this chapter:
64 |
65 | Or this:
66 |
67 | > In this section, these terms shall be defined as follows:
68 |
69 | “Scope indicators” are the phrases that appear immediately prior to the name of the structural unit (e.g., "title," "chapter," etc.) to which the definitions apply. By default, scope indicators look like this:
70 |
71 | ~~~
72 | $scope_indicators = array( ' are used in this ',
73 | ' when used in this ',
74 | ' for purposes of this ',
75 | ' for the purpose of this ',
76 | ' in this ',
77 | );
78 | ~~~
79 |
80 | Your legal code is unlikely to use this exact set of scope indicators. You'll need to read through a bunch of laws to get a handle on the candidate phrases, and list those here. Again, you must use the phrase that appears *immediately* prior to the name of the structural unit. If this does not fit how your legal code describes scope, then you'll need to make some modifications to `extract_definitions()`. Specifically this bit:
81 |
82 | ~~~
83 | /*
84 | * Now figure out the specified scope by examining the text that appears
85 | * immediately after the scope indicator. Pull out as many characters as the
86 | * length of the longest structural label.
87 | */
88 | $phrase = substr( $paragraph, ($pos + strlen($scope_indicator)), $longest_label );
89 | ~~~
90 |
91 | You'll just need to grab a different chunk of text surrounding `$scope_indicator`.
92 |
93 | If you get this wrong, it's not disasterous. If you include a scope indicator erroneously, almost certainly the only effect will be that the parser does a bit more work that it has to. If you fail to include a scope indicator, the definitions will still be detected, extracted, and stored, but their scope will be limited to the law in which they appear, as that is the most cautious default.
94 |
95 |
96 | #### Linking phrases
97 |
98 | The second and final set of phrases to be customized are the linking phrases, which is the word, words, or characters that connect a term to its definitions. For example:
99 |
100 | > “Person” shall include individuals, a trust, an estate, a partnership, an association, an order, a corporation, or any other legal or commercial entity.
101 |
102 | Or:
103 |
104 | > “Decree”: Shall be used interchangeably with “judgment,” and shall include orders or awards.
105 |
106 | In the former example, "shall include" is the linking phrase. In the latter, ": " is the linking phrase. (Admittedly, ": " is not a phrase, but it's also not a common construct within legal codes.)
107 |
108 | We use these linking phrases to separate a term from its definition. They're stored in an array, named `$linking_phrases`, which looks like this by default:
109 |
110 | ~~~
111 | $linking_phrases = array( ' mean ',
112 | ' means ',
113 | ' shall include ',
114 | ' includes ',
115 | ' has the same meaning as ',
116 | ' shall be construed ',
117 | ' shall also be construed to mean ',
118 | );
119 | ~~~
120 |
121 | As with scope indicators, it is necessary to survey your legal code, to see how it links terms to their definitions, in order to populate your list. Odds aren't bad that it'll look rather like the default list.
122 |
123 | If your linking phrases list is overly broad, the only effect will be to imperceptably slow down The State Decoded's parser. If it's overly narrow, the effect will be to omit affected terms and definitions from your dictionary—The State Decoded will simply have no idea that it's looking at a definition.
124 |
125 | ### Quotation marks
126 |
127 | There is a third attribute of which to be aware, although it's not a trivial customization like scope indicators and linking phrases. The State Decoded assumes that defined terms are contained within quotes, like this:
128 |
129 | > “Decree”: Shall include orders or awards.
130 |
131 | Those can be straight quotes or angled quotes (aka "smart quotes"), but the terms must be within quotes. We use quotation marks for two reasons. The first is to determine whether to examine a paragraph to see if it contains a definition. No quotes, no definition. The second is to determine which words are the term being defined.
132 |
133 | If your legal code does not insert defined terms within quotes, don't panic. While there is no friendly configuration option to address this, it's not a tough customization.
134 |
135 | The first change you'd need to make is to the conditional that checks whether a quotation mark is present within a paragraph:
136 |
137 | ~~~
138 | /*
139 | * All defined terms are surrounded by quotation marks, so let's use that as a criteria
140 | * to round down our candidate paragraphs.
141 | */
142 | if (strpos($paragraph, $quote_sample) !== FALSE)
143 | {
144 | ~~~
145 |
146 | Best-case, there will be some other wrapper around each definition (e.g., `Decree: Shall include orders or awards.`), in which case you might turn the conditional into this:
147 |
148 | ~~~
149 | if (strpos($paragraph, '') !== FALSE)
150 | ~~~
151 |
152 | Worst-case, you'd have this examine every single paragraph (e.g., `if (1 == 1)`, or just remove the `if(…){…}` wrapper entirely.)
153 |
154 | Then, throughout the contents of `if (strpos($paragraph, $quote_sample) !== FALSE) { … }`, you'd need to replace references to quotation marks to the applicable characters, including in the regular expression that extracts the defined term:
155 |
156 | ~~~
157 | preg_match_all('/("|“)([A-Za-z]{1})([A-Za-z,\'\s-]*)([A-Za-z]{1})("|”)/', $paragraph, $terms);
158 | ~~~
159 |
160 | Specifically, it's the two instances of `("|”)` that would need to be replaced with the new character or characters used to enclose the defined term.
161 |
162 | If there are no characters used to enclose the defined term, this is still very fixable, although a bit outside of the scope of this guide.
163 |
164 |
165 | ## extract_references()
166 |
167 | This method should not require any customization. Its job is to scan each section for mentions of other sections to create a cross reference list.
168 |
169 | ## extract_history()
170 |
171 | Turns the often-cryptic history sections within nearly every law into standardized data. For instance:
172 |
173 | ~~~
174 | 1995, c. 837, § 18.2-340.32; 1997, cc. 777, 838
175 | ~~~
176 |
177 | This tell us that in the 1995 Acts of Assembly, the instant law was modified (or perhaps created), as recorded in chapter 837, and the law was then known as § 18.2-340.32, though it as since been renumbered. And then in the 1997 Acts of Assembly, it was modified twice, in chapters 777 and 838. The job of `extract_history()` is to turn this data into an object, rather than storing it as a single string of text. Inevitably, it will require extensive modification to work with each state's unique method of storing history data, although this is both technically and logistically straightforward.
178 |
179 | ## create_structure
180 |
181 | The only customization that may be helpful here is to populate the `order_by` field in the `structure` table. Many legal codes are ordered in such a way that no standard SQL-based ordering can display them properly (e.g., 4.8, 4.9, 4.10, 4.11, rather than the mathematically proper 4.10, 4.11, 4.8, 4.9, or 4.8, 4.8:A, 4.8:B, 4.8:C). For such codes it may be helpful to populate `order_by` within the SQL query in this method, by whatever ordering mechanisms are available.
182 |
183 | # Working with Metadata
184 |
185 | You may have additional properties, data, and fields in your legal code that The State Decoded does not know about out-of-the-box. To include these, you'll need to store them in the law's `metadata`. For example, for the Virginia code, we include court cases via The Court Listener which reference a given law.
186 |
187 | This data is stored in the `laws_meta` database table. However, instead of directly adding records to this table, you can use an existing instance of the Law class, add your metadata to the object, and call `store_metadata()` to save it. Here's an example, from the `class.State-sample.inc.php` code:
188 |
189 | ```
190 | // Store these decisions in the metadata table.
191 | $law = new Law();
192 | $law->section_id = $this->section_id;
193 |
194 | $law->metadata->{0} = new stdClass();
195 | $law->metadata->{0}->key = 'court_decisions';
196 | $law->metadata->{0}->value = json_encode($this->decisions);
197 |
198 | $law->store_metadata();
199 | ```
200 |
201 | You can create metadata at any point after the law has been created in the parser (the call to the `Parser->store()`), but in most cases you'll want to store it before the laws are exported (`ParserController->export()`), so that the metadata can appear in the exported data files.
202 |
203 | To show this data on a law's page, you'lll need to edit the `htdocs\law.php` file to format the data appropriately. Again, refer to the `court_decisions` example in that file for reference – in most cases, your data will be available on the law as `$law->metadata->your_field`.
204 |
205 | You may also store metadata on a structure, but you will need to manage this manually. The metadata for structures is stored in the `structure.metadata` field as an object that has been run through the `serialize()` function. Be careful to load the structure's previous metadata when adding your new metadata, so as not to overwrite previously-created data.
206 |
--------------------------------------------------------------------------------
/release-process.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Release Process
3 | layout: default
4 | ---
5 |
6 | * review all code to make sure no alpha-testing code has slipped in
7 | * run a from-scratch test deployment
8 | * run site with E_NOTICE errors enabled
9 | * validate site template
10 | * validate CSS
11 | * update the docblock at the head of each document
12 | * update CHANGELOG.md based on both the closed issues and the actual changes
13 | * review LICENSE to make sure that any newly incorporated packages are credited
14 | * review README.md
15 | * tag the release on GitHub
16 | * create a new Vagrant image
17 | * upload it and publish the URL
18 | * write a blog entry announcing it
19 | * tweet about it
20 | * inform every known State Decoded user
21 |
--------------------------------------------------------------------------------
/search.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Search
3 | layout: default
4 | ---
5 |
6 | *Note: This page is actively under development. At present, it's more of a collection of thoughts than actual documentation.*
7 |
8 | ##solr_home directory
9 |
10 | The `/solr_home/` directory can be kept anywhere. There's no functional need for it to be available within the scope of the website. By default, it lives in parallel to `/htdocs/` and `/includes/`. Its location is only relevant when starting Solr, which is when the path is provided, e.g. `-Dsolr.solr.home=/var/www/example.com/solr_home/`.
11 |
12 | ## Tag weighting
13 |
14 | In `/solr_home/statedecoded/conf/solrconfig.xml`, the request handler for standard searches (``) is configured to give tags the same weight as all other indexed fields. Depending on the source of your tags, you may be well served by adjusting this number.
15 |
16 | For instance, if your tags are well written, accurate, and not over-broad, then you could increase its weight from the (implied) default of 1.0, and take it up to 2.0, 5.0, even 10.0, for Solr to value tags, in determining the relevance of a given law, that multiple of times above all other fields.
17 |
18 | On the other hand, if your tags are good-not-great, then you'd want to decrease the weight of tags, down to .5 or .2 or even .1, to have Solr value other fields beyond tags, but still include tags in its index.
19 |
20 | This is done by appending `^5` (to weight tags at 500% that of other fields) or `^.1` (to weight tags at just 10% of other fields) after `tags` within the `` tag, e.g.:
21 |
22 | ~~~
23 |
24 | catch_line
25 | tags^5
26 | text
27 | structure
28 | section_ancestor^10
29 | section_descendent^10
30 | refers_to_descendent
31 | refers_to_ancestor
32 | referred_to_by_descendent
33 | referred_to_by_ancestor
34 | term
35 | definition
36 |
37 | ~~~
38 |
39 | ## Section number tokenizer
40 | Within `/solr_home/statedecoded/conf/schema.xml` there is a tokenizer that indexes cross-references mentions of other laws within a law. The job of this tokenizer is to identify the pattern of a cross-reference, treat it as a single unit of data (instead of inadvertently breaking it up), and index it.
41 |
42 | Here's what the tokenizer looks like:
43 |
44 |
45 | ~~~
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | ~~~
62 |
63 | As of this writing, this tokenizer is decoupled from the configuration performed in `/includes/config-sample.inc.php`, which is to say that it may require manual configuration. As provided, it should work for most legal codes.
64 |
--------------------------------------------------------------------------------
/stylesheets/pygment_trac.css:
--------------------------------------------------------------------------------
1 | .highlight { background: #ffffff; }
2 | .highlight .c { color: #999988; font-style: italic } /* Comment */
3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
4 | .highlight .k { font-weight: bold } /* Keyword */
5 | .highlight .o { font-weight: bold } /* Operator */
6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
12 | .highlight .ge { font-style: italic } /* Generic.Emph */
13 | .highlight .gr { color: #aa0000 } /* Generic.Error */
14 | .highlight .gh { color: #999999 } /* Generic.Heading */
15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
17 | .highlight .go { color: #888888 } /* Generic.Output */
18 | .highlight .gp { color: #555555 } /* Generic.Prompt */
19 | .highlight .gs { font-weight: bold } /* Generic.Strong */
20 | .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */
21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */
22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */
23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */
24 | .highlight .kn { font-weight: bold } /* Keyword.Namespace */
25 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */
26 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */
27 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
28 | .highlight .m { color: #009999 } /* Literal.Number */
29 | .highlight .s { color: #d14 } /* Literal.String */
30 | .highlight .na { color: #008080 } /* Name.Attribute */
31 | .highlight .nb { color: #0086B3 } /* Name.Builtin */
32 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
33 | .highlight .no { color: #008080 } /* Name.Constant */
34 | .highlight .ni { color: #800080 } /* Name.Entity */
35 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
36 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
37 | .highlight .nn { color: #555555 } /* Name.Namespace */
38 | .highlight .nt { color: #000080 } /* Name.Tag */
39 | .highlight .nv { color: #008080 } /* Name.Variable */
40 | .highlight .ow { font-weight: bold } /* Operator.Word */
41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
42 | .highlight .mf { color: #009999 } /* Literal.Number.Float */
43 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */
44 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */
45 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */
46 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */
47 | .highlight .sc { color: #d14 } /* Literal.String.Char */
48 | .highlight .sd { color: #d14 } /* Literal.String.Doc */
49 | .highlight .s2 { color: #d14 } /* Literal.String.Double */
50 | .highlight .se { color: #d14 } /* Literal.String.Escape */
51 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */
52 | .highlight .si { color: #d14 } /* Literal.String.Interpol */
53 | .highlight .sx { color: #d14 } /* Literal.String.Other */
54 | .highlight .sr { color: #009926 } /* Literal.String.Regex */
55 | .highlight .s1 { color: #d14 } /* Literal.String.Single */
56 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */
57 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
58 | .highlight .vc { color: #008080 } /* Name.Variable.Class */
59 | .highlight .vg { color: #008080 } /* Name.Variable.Global */
60 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */
61 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
62 |
63 | .type-csharp .highlight .k { color: #0000FF }
64 | .type-csharp .highlight .kt { color: #0000FF }
65 | .type-csharp .highlight .nf { color: #000000; font-weight: normal }
66 | .type-csharp .highlight .nc { color: #2B91AF }
67 | .type-csharp .highlight .nn { color: #000000 }
68 | .type-csharp .highlight .s { color: #A31515 }
69 | .type-csharp .highlight .sc { color: #A31515 }
70 |
--------------------------------------------------------------------------------
/stylesheets/styles.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700);
2 |
3 | body {
4 | padding:50px;
5 | font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
6 | color:#777;
7 | font-weight:300;
8 | }
9 |
10 | h1, h2, h3, h4, h5, h6 {
11 | color:#222;
12 | margin:0 0 20px;
13 | }
14 |
15 | p, ul, ol, table, pre, dl {
16 | margin:0 0 20px;
17 | }
18 |
19 | h1, h2, h3 {
20 | line-height:1.1;
21 | }
22 |
23 | h1 {
24 | font-size:28px;
25 | }
26 |
27 | h2 {
28 | color:#393939;
29 | }
30 |
31 | h3, h4, h5, h6 {
32 | color:#494949;
33 | }
34 |
35 | a {
36 | color:#39c;
37 | font-weight:400;
38 | text-decoration:none;
39 | }
40 |
41 | a small {
42 | font-size:11px;
43 | color:#777;
44 | margin-top:-0.6em;
45 | display:block;
46 | }
47 |
48 | .wrapper {
49 | width:860px;
50 | margin:0 auto;
51 | }
52 |
53 | blockquote {
54 | border-left:1px solid #e5e5e5;
55 | margin:0;
56 | padding:0 0 0 20px;
57 | font-style:italic;
58 | }
59 |
60 | code, pre {
61 | font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal;
62 | color:#333;
63 | font-size:12px;
64 | }
65 |
66 | pre {
67 | padding:8px 15px;
68 | background: #f8f8f8;
69 | border-radius:5px;
70 | border:1px solid #e5e5e5;
71 | overflow-x: auto;
72 | }
73 |
74 | table {
75 | width:100%;
76 | border-collapse:collapse;
77 | }
78 |
79 | th, td {
80 | text-align:left;
81 | padding:5px 10px;
82 | border-bottom:1px solid #e5e5e5;
83 | }
84 |
85 | dt {
86 | color:#444;
87 | font-weight:700;
88 | }
89 |
90 | th {
91 | color:#444;
92 | }
93 |
94 | img {
95 | max-width:100%;
96 | }
97 |
98 | header {
99 | width:270px;
100 | float:left;
101 | position:fixed;
102 | }
103 |
104 | header ul {
105 | list-style:none;
106 | height:40px;
107 |
108 | padding:0;
109 |
110 | background: #eee;
111 | background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%);
112 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));
113 | background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
114 | background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
115 | background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
116 | background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
117 |
118 | border-radius:5px;
119 | border:1px solid #d2d2d2;
120 | box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0;
121 | width:270px;
122 | }
123 |
124 | header li {
125 | width:89px;
126 | float:left;
127 | border-right:1px solid #d2d2d2;
128 | height:40px;
129 | }
130 |
131 | header ul a {
132 | line-height:1;
133 | font-size:11px;
134 | color:#999;
135 | display:block;
136 | text-align:center;
137 | padding-top:6px;
138 | height:40px;
139 | }
140 |
141 | strong {
142 | color:#222;
143 | font-weight:700;
144 | }
145 |
146 | header ul li + li {
147 | width:88px;
148 | border-left:1px solid #fff;
149 | }
150 |
151 | header ul li + li + li {
152 | border-right:none;
153 | width:89px;
154 | }
155 |
156 | header ul a strong {
157 | font-size:14px;
158 | display:block;
159 | color:#222;
160 | }
161 |
162 | section {
163 | width:500px;
164 | float:right;
165 | padding-bottom:50px;
166 | }
167 |
168 | small {
169 | font-size:11px;
170 | }
171 |
172 | hr {
173 | border:0;
174 | background:#e5e5e5;
175 | height:1px;
176 | margin:0 0 20px;
177 | }
178 |
179 | footer {
180 | width:270px;
181 | float:left;
182 | position:fixed;
183 | bottom:50px;
184 | }
185 |
186 | @media print, screen and (max-width: 960px) {
187 |
188 | div.wrapper {
189 | width:auto;
190 | margin:0;
191 | }
192 |
193 | header, section, footer {
194 | float:none;
195 | position:static;
196 | width:auto;
197 | }
198 |
199 | header {
200 | padding-right:320px;
201 | }
202 |
203 | section {
204 | border:1px solid #e5e5e5;
205 | border-width:1px 0;
206 | padding:20px 0;
207 | margin:0 0 20px;
208 | }
209 |
210 | header a small {
211 | display:inline;
212 | }
213 |
214 | header ul {
215 | position:absolute;
216 | right:50px;
217 | top:52px;
218 | }
219 | }
220 |
221 | @media print, screen and (max-width: 720px) {
222 | body {
223 | word-wrap:break-word;
224 | }
225 |
226 | header {
227 | padding:0;
228 | }
229 |
230 | header ul, header p.view {
231 | position:static;
232 | }
233 |
234 | pre, code {
235 | word-wrap:normal;
236 | }
237 | }
238 |
239 | @media print, screen and (max-width: 480px) {
240 | body {
241 | padding:15px;
242 | }
243 |
244 | header ul {
245 | display:none;
246 | }
247 | }
248 |
249 | @media print {
250 | body {
251 | padding:0.4in;
252 | font-size:12pt;
253 | color:#444;
254 | }
255 | }
256 |
--------------------------------------------------------------------------------
/stylesheets/stylesheet.css:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Slate Theme for GitHub Pages
3 | by Jason Costello, @jsncostello
4 | *******************************************************************************/
5 |
6 | @import url(pygment_trac.css);
7 |
8 | /*******************************************************************************
9 | MeyerWeb Reset
10 | *******************************************************************************/
11 |
12 | html, body, div, span, applet, object, iframe,
13 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
14 | a, abbr, acronym, address, big, cite, code,
15 | del, dfn, em, img, ins, kbd, q, s, samp,
16 | small, strike, strong, sub, sup, tt, var,
17 | b, u, i, center,
18 | dl, dt, dd, ol, ul, li,
19 | fieldset, form, label, legend,
20 | table, caption, tbody, tfoot, thead, tr, th, td,
21 | article, aside, canvas, details, embed,
22 | figure, figcaption, footer, header, hgroup,
23 | menu, nav, output, ruby, section, summary,
24 | time, mark, audio, video {
25 | margin: 0;
26 | padding: 0;
27 | border: 0;
28 | font: inherit;
29 | vertical-align: baseline;
30 | }
31 |
32 | /* HTML5 display-role reset for older browsers */
33 | article, aside, details, figcaption, figure,
34 | footer, header, hgroup, menu, nav, section {
35 | display: block;
36 | }
37 |
38 | ol, ul {
39 | list-style: none;
40 | }
41 |
42 | blockquote, q {
43 | }
44 |
45 | table {
46 | border-collapse: collapse;
47 | border-spacing: 0;
48 | }
49 |
50 | /*******************************************************************************
51 | Theme Styles
52 | *******************************************************************************/
53 |
54 | body {
55 | box-sizing: border-box;
56 | color:#373737;
57 | background: #212121;
58 | font-size: 16px;
59 | font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
60 | line-height: 1.5;
61 | -webkit-font-smoothing: antialiased;
62 | }
63 |
64 | h1, h2, h3, h4, h5, h6 {
65 | margin: 10px 0;
66 | font-weight: 700;
67 | color:#222222;
68 | font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
69 | letter-spacing: -1px;
70 | }
71 |
72 | h1 {
73 | font-size: 36px;
74 | font-weight: 700;
75 | }
76 |
77 | h2 {
78 | padding-bottom: 10px;
79 | font-size: 32px;
80 | background: url('../images/bg_hr.png') repeat-x bottom;
81 | }
82 |
83 | h3 {
84 | font-size: 24px;
85 | }
86 |
87 | h4 {
88 | font-size: 21px;
89 | }
90 |
91 | h5 {
92 | font-size: 18px;
93 | }
94 |
95 | h6 {
96 | font-size: 16px;
97 | }
98 |
99 | p {
100 | margin: 10px 0 15px 0;
101 | }
102 |
103 | footer p {
104 | color: #f2f2f2;
105 | }
106 |
107 | a {
108 | text-decoration: none;
109 | color: #007edf;
110 | text-shadow: none;
111 |
112 | transition: color 0.5s ease;
113 | transition: text-shadow 0.5s ease;
114 | -webkit-transition: color 0.5s ease;
115 | -webkit-transition: text-shadow 0.5s ease;
116 | -moz-transition: color 0.5s ease;
117 | -moz-transition: text-shadow 0.5s ease;
118 | -o-transition: color 0.5s ease;
119 | -o-transition: text-shadow 0.5s ease;
120 | -ms-transition: color 0.5s ease;
121 | -ms-transition: text-shadow 0.5s ease;
122 | }
123 |
124 | #main_content a:hover {
125 | color: #0069ba;
126 | text-shadow: #0090ff 0px 0px 2px;
127 | }
128 |
129 | footer a:hover {
130 | color: #43adff;
131 | text-shadow: #0090ff 0px 0px 2px;
132 | }
133 |
134 | em {
135 | font-style: italic;
136 | }
137 |
138 | strong {
139 | font-weight: bold;
140 | }
141 |
142 | img {
143 | position: relative;
144 | margin: 0 auto;
145 | max-width: 739px;
146 | padding: 5px;
147 | margin: 10px 0 10px 0;
148 | border: 1px solid #ebebeb;
149 |
150 | box-shadow: 0 0 5px #ebebeb;
151 | -webkit-box-shadow: 0 0 5px #ebebeb;
152 | -moz-box-shadow: 0 0 5px #ebebeb;
153 | -o-box-shadow: 0 0 5px #ebebeb;
154 | -ms-box-shadow: 0 0 5px #ebebeb;
155 | }
156 |
157 | pre, code {
158 | width: 100%;
159 | color: #222;
160 | background-color: #fff;
161 |
162 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
163 | font-size: 14px;
164 |
165 | border-radius: 2px;
166 | -moz-border-radius: 2px;
167 | -webkit-border-radius: 2px;
168 |
169 |
170 |
171 | }
172 |
173 | pre {
174 | width: 100%;
175 | padding: 10px;
176 | box-shadow: 0 0 10px rgba(0,0,0,.1);
177 | overflow: auto;
178 | }
179 |
180 | code {
181 | padding: 3px;
182 | margin: 0 3px;
183 | box-shadow: 0 0 10px rgba(0,0,0,.1);
184 | }
185 |
186 | pre code {
187 | display: block;
188 | box-shadow: none;
189 | }
190 |
191 | blockquote {
192 | color: #666;
193 | margin-bottom: 20px;
194 | padding: 0 0 0 20px;
195 | border-left: 3px solid #bbb;
196 | }
197 |
198 | ul, ol, dl {
199 | margin-bottom: 15px
200 | }
201 |
202 | ul li {
203 | list-style: inside;
204 | padding-left: 20px;
205 | }
206 |
207 | ol li {
208 | list-style: decimal inside;
209 | padding-left: 20px;
210 | }
211 |
212 | dl dt {
213 | font-weight: bold;
214 | }
215 |
216 | dl dd {
217 | padding-left: 20px;
218 | font-style: italic;
219 | }
220 |
221 | dl p {
222 | padding-left: 20px;
223 | font-style: italic;
224 | }
225 |
226 | hr {
227 | height: 1px;
228 | margin-bottom: 5px;
229 | border: none;
230 | background: url('../images/bg_hr.png') repeat-x center;
231 | }
232 |
233 | table {
234 | border: 1px solid #373737;
235 | margin-bottom: 20px;
236 | text-align: left;
237 | }
238 |
239 | th {
240 | font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
241 | padding: 10px;
242 | background: #373737;
243 | color: #fff;
244 | }
245 |
246 | td {
247 | padding: 10px;
248 | border: 1px solid #373737;
249 | }
250 |
251 | form {
252 | background: #f2f2f2;
253 | padding: 20px;
254 | }
255 |
256 | img {
257 | width: 100%;
258 | max-width: 100%;
259 | }
260 |
261 | /*******************************************************************************
262 | Full-Width Styles
263 | *******************************************************************************/
264 |
265 | .outer {
266 | width: 100%;
267 | }
268 |
269 | .inner {
270 | position: relative;
271 | max-width: 640px;
272 | padding: 20px 10px;
273 | margin: 0 auto;
274 | }
275 |
276 | #forkme_banner {
277 | display: block;
278 | position: absolute;
279 | top:0;
280 | right: 10px;
281 | z-index: 10;
282 | padding: 10px 50px 10px 10px;
283 | color: #fff;
284 | background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%;
285 | font-weight: 700;
286 | box-shadow: 0 0 10px rgba(0,0,0,.5);
287 | border-bottom-left-radius: 2px;
288 | border-bottom-right-radius: 2px;
289 | }
290 |
291 | #header_wrap {
292 | background: #212121;
293 | background: -moz-linear-gradient(top, #373737, #212121);
294 | background: -webkit-linear-gradient(top, #373737, #212121);
295 | background: -ms-linear-gradient(top, #373737, #212121);
296 | background: -o-linear-gradient(top, #373737, #212121);
297 | background: linear-gradient(top, #373737, #212121);
298 | }
299 |
300 | #header_wrap .inner {
301 | padding: 50px 10px 30px 10px;
302 | }
303 |
304 | #project_title {
305 | margin: 0;
306 | color: #fff;
307 | font-size: 42px;
308 | font-weight: 700;
309 | text-shadow: #111 0px 0px 10px;
310 | }
311 |
312 | #project_tagline {
313 | color: #fff;
314 | font-size: 24px;
315 | font-weight: 300;
316 | background: none;
317 | text-shadow: #111 0px 0px 10px;
318 | }
319 |
320 | #downloads {
321 | position: absolute;
322 | width: 210px;
323 | z-index: 10;
324 | bottom: -40px;
325 | right: 0;
326 | height: 70px;
327 | background: url('../images/icon_download.png') no-repeat 0% 90%;
328 | }
329 |
330 | .zip_download_link {
331 | display: block;
332 | float: right;
333 | width: 90px;
334 | height:70px;
335 | text-indent: -5000px;
336 | overflow: hidden;
337 | background: url(../images/sprite_download.png) no-repeat bottom left;
338 | }
339 |
340 | .tar_download_link {
341 | display: block;
342 | float: right;
343 | width: 90px;
344 | height:70px;
345 | text-indent: -5000px;
346 | overflow: hidden;
347 | background: url(../images/sprite_download.png) no-repeat bottom right;
348 | margin-left: 10px;
349 | }
350 |
351 | .zip_download_link:hover {
352 | background: url(../images/sprite_download.png) no-repeat top left;
353 | }
354 |
355 | .tar_download_link:hover {
356 | background: url(../images/sprite_download.png) no-repeat top right;
357 | }
358 |
359 | #main_content_wrap {
360 | background: #f2f2f2;
361 | border-top: 1px solid #111;
362 | border-bottom: 1px solid #111;
363 | }
364 |
365 | #main_content {
366 | padding-top: 40px;
367 | }
368 |
369 | #footer_wrap {
370 | background: #212121;
371 | }
372 |
373 |
374 |
375 | /*******************************************************************************
376 | Small Device Styles
377 | *******************************************************************************/
378 |
379 | @media screen and (max-width: 480px) {
380 | body {
381 | font-size:14px;
382 | }
383 |
384 | #downloads {
385 | display: none;
386 | }
387 |
388 | .inner {
389 | min-width: 320px;
390 | max-width: 480px;
391 | }
392 |
393 | #project_title {
394 | font-size: 32px;
395 | }
396 |
397 | h1 {
398 | font-size: 28px;
399 | }
400 |
401 | h2 {
402 | font-size: 24px;
403 | }
404 |
405 | h3 {
406 | font-size: 21px;
407 | }
408 |
409 | h4 {
410 | font-size: 18px;
411 | }
412 |
413 | h5 {
414 | font-size: 14px;
415 | }
416 |
417 | h6 {
418 | font-size: 12px;
419 | }
420 |
421 | code, pre {
422 | min-width: 320px;
423 | max-width: 480px;
424 | font-size: 11px;
425 | }
426 |
427 | }
428 |
--------------------------------------------------------------------------------
/templates.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Templates
3 | layout: default
4 | ---
5 |
6 | # Contents
7 | {:.no_toc}
8 |
9 | * Will be replaced with the ToC, excluding the "Contents" header
10 | {:toc}
11 |
12 | # Master template file
13 | Duplicate `htdocs/themes/StateDecoded2013/` (to, say, `htdocs/themes/Kansas/`), then edit `THEME_NAME` in `includes/config.inc.php` to read `Kansas` instead of `StateDecoded2013`. The contents of the new `Kansas` directory are now your site template.
14 |
15 | # Images
16 | There is a [State Decoded Assets repository](https://github.com/statedecoded/statedecoded-assets/) that contains PSD files of page mockups and a favicon. These may be modified to customize the site's images as you see fit.
17 |
18 | # CSS
19 | If you choose to duplicate the default “State Decoded 2013“ theme, then you will be happiest if you do not edit the existing CSS files directly. Instead, create a new CSS file (e.g., `htdocs/themes/Kansas/static/css/kansas.css`) and start it with the following line:
20 |
21 | ~~~
22 | @import url("application.css");
23 | ~~~
24 |
25 | Then add your CSS declarations on top of that. This way, as subsequent releases of The State Decoded add modify the bundled CSS to add new functionality, you will gain that functionality in your own design by simply copying over the new `application.css`. Then, in your template (e.g., `htdocs/themes/Kansas/default.inc.php`), have it load `kansas.css` instead of `application.css`.
26 |
27 | Better still, if you're comfortable with SCSS, do the same, but by creating a new SCSS file (e.g., `htdocs/themes/Kansas/static/scss/kansas.scss`) that leads off by importing `application.scss`, and then use that to generate `htdocs/themes/Kansas/static/css/application.css`.
28 |
29 | # Caching
30 | If you're running Varnish or mod_pagespeed on your server, you'll need to clear out your cache after making design changes. That's important for Varnish, which caches whole pages. mod_pagespeed should automatically expire its cached assets (Javascript, CSS, and images) when you change them, but if it doesn't, you'll need [flush its cache manually](https://developers.google.com/speed/pagespeed/module/system#flush_cache).
31 |
32 | # Home Page Layout
33 | The home page is found at `home.php`, not `index.php`. (`index.php` is the file through which all page requests on the site are piped.)
34 |
35 | If you have an introductory video that you want to display on the home page, uncomment the `
[…]
` stanza from `htdocs/home.php` and modify appropriately to link to your video.
36 |
37 | # Favicons, Apple Touch Icons
38 |
39 | Each of these icons should somehow correlate to the political entity's legal code. With Virginia, we used the seal icon that was created for the site. The larger touch icons have bitmapped 0 and 1s fading across, representing digital bits being "decoded" as it were. Feel free to edit the master images in [the State Decoded Assets repository](https://github.com/statedecoded/statedecoded-assets) to suit your needs. We recommend running any images through [ImageOptim](http://imageoptim.com) to squeeze out excess file size.
40 |
41 | # Sass, Compass, etc.
42 |
43 | This site was built with future flexibility and reuse in mind. To that end, the site basically is a style guide as well as a design. We use Sass/SCSS to allow the power of variables in CSS. This makes it easy to rapidly change colors and fonts without having to do massive find-and-replace or worry about color math variations in Photoshop.
44 |
45 | This does create a layer of complexity, but a worthwhile one. You, as an end user, can write regular CSS in an SCSS file and it will compile normally.
46 |
47 | To compile the SCSS into CSS, you need to run CodeKit, Scout, CompassApp, or do a manual setup with Ruby on your system. This is documented on [the Compass site](http://compass-style.org/install/).
48 |
49 | # Media Queries
50 |
51 | The site is defined with three breakpoints:
52 |
53 | * Handheld/iPhone
54 | * Tablet/iPad (Portrait)
55 | * Everything else
56 |
57 | # Creating New Pages
58 |
59 | You may add new pages to the site by simply including `HTML` or `PHP` files inside of the `htdocs` directory of the site. You can then reference those files by name. Similarly, any images or other assets in that directory can be used on the site.
60 |
61 | If you would like to use the template engine of The State Decoded instead of having to include an entire page, simply create a new PHP file with at least the following contents, replacing `$body` with your content.
62 |
63 | ```
64 | /*
65 | * Create a container for our content.
66 | */
67 | $content = new Content();
68 |
69 | $body = 'Hello World';
70 |
71 | /*
72 | * Put the shorthand $body variable into its proper place.
73 | */
74 | $content->set('body', $body);
75 |
76 | /*
77 | * Parse the template, which is a shortcut for a few steps that culminate in sending the content
78 | * to the browser.
79 | */
80 | $template = Template::create();
81 | $template->parse($content);
82 | ```
83 |
84 | There are other fields available on a page, including the page title and heading. Please have a look at the other pages on the site and the theme's `default.inc.php` template file for specific fields that are available to change via the `$content->set` method.
85 |
86 | To have the page appear without the file extension, as the About page and others do, you'll need to add it to the routing system. The routing system uses simple [regular expressions](http://www.regular-expressions.info/) to match routes. Simply add a line to the `Specific Routes` section of the `includes/routes.inc.php` file with your page's name, route structure, and filename like this:
87 |
88 | ```
89 | $router->addRoute('contact', '^/contact/$', 'contact.php');
90 | ```
91 |
92 |
93 | # Editing Help Content
94 |
95 | To customize the help content of any section, you'll need to edit the `htdocs/content/help.json` file. There, you'll need to give the help content a title, a brief description, and the full content that should appear in the modal popup.
96 |
--------------------------------------------------------------------------------
/xml-format.html:
--------------------------------------------------------------------------------
1 | ---
2 | title: XML Format
3 | layout: default
4 | ---
5 |
6 |
The State Decoded parser can either be modified to use bespoke PHP to parse a legal code in its native format, or it can parse a prescribed XML format. This is a totally invented XML format. There is no legal code that is provided in this format. It is provided as an option because, via XSLT, it can be substantially easier to convert an existing XML to this format than to write a parser for it in PHP.
7 |
8 |
The State Decoded includes a sample XSLT file on which you can base your own XSLT. It is well commented and verbose, so even if you’re not familiar with XSLT, you’ve got a fighting chance of transforming your XML to The State Decoded’s format. If the legal code that you are ingesting is in Lexis-Nexis' XML format (which sometimes travels under the name of “legislativedoc v1”), then use lexis-nexis.xsl, which is included with The State Decoded.
9 |
10 |
Note that this is not an effort to create a standard interchange or storage format for legal codes. This exists solely as a convenience for importing data into The State Decoded.
11 |
12 |
Terminology
13 |
14 | Legal codes throughout the U.S. all use different terminology (e.g., "statutes" vs "code" vs "laws"). We need to adopt some terminology here, and while it can't be the right terminology everywhere, we hope to avoid any disputes about what exactly is the right terminology. The terminology we've adopted was the simplest that also reflected the reality of the data. A lot of people implementing The State Decoded are programmers, not attorneys, and the terminology that the project uses needs to reflect the reality of that user base.
15 |
16 | Below, the word "law" refers to what some jurisdictions would call a section, and it's usually prefixed with the § symbol. It corresponds to a single page on a State Decoded website.
17 |
18 | Within a "law", we use "section" elements to represent the hierarchical structure of the paragraphs within it. In some jurisdictions this would be called a subsection. A "section" corresponds to a paragraph plus any logically nested (typically indented) content within it.
19 |
20 |
Descriptive Specifications
21 |
22 |
23 |
There must be one file per law.
24 |
All files must be in the same directory.
25 |
The names of the files are irrelevant.
26 |
Every file contains both structural data about its container—which chapter/title/part/article/etc. that it's within—and data about the law itself.
27 |
Text must be broken up by subsection, rather than provided as a single block of text, unless the text of the law does not have subsections.
28 |
Subsections may be nested.
29 |
30 |
31 |
This being open source software, some relatively simple tweaks to Parser::iterate and Parser::parse make all of these specifications malleable.
32 |
33 |
Fields
34 |
35 |
36 |
law: the container for all other fields—required
37 |
structure: the container for structural units (chapters, titles, articles, parts, etc.)—required
38 |
unit: a single structural unit that contains this law—required
39 |
label: the type of structural unit that this is (chapter, title, article, part, etc.)—required
40 |
identifier: the unique identifier for this structural unit (but not necessarily globally unique!), almost always a number (e.g., 18.2, 6)—required
41 |
orderby: when listing all structural units of this label, in what ordinal position this structural unit should appear—optional
42 |
level: a whole number, starting at one, indicating the depth of this structural unit—required
43 |
sectionnumber: the unique identifier for this law—required
44 |
catchline: the title of this law—required
45 |
orderby: when listing all laws within this structural unit, in what ordinal position this law should appear—optional
46 |
text: the container for the text of the law itself—required
47 |
section: a single labelled section of a law—optional
48 |
prefix: the identifying label for this section (e.g., A, 6, vi)—required
49 |
type: the type of material within this section; default is text, other options are "table" and "image"—optional
50 |
history: the textual description of the history of amendments to this law—optional
51 |
metadata: a container for any additional fields, which will be stored as key:value in the laws_meta table—optional; values of true and false will be stored in the database as y and n, respectively, but converted back to true and false within the internal and external APIs
Here is a complete, populated sample XML file that includes every available parameter.
97 |
98 |
99 | <?xml version="1.0" encoding="utf-8"?>
100 | <law>
101 | <structure>
102 | <unit label="title" identifier="18.2" order_by="18.2" level="1">Crimes and Offenses Generally</unit>
103 | <unit label="chapter" identifier="6" order_by="6" level="2">Crimes Involving Fraud</unit>
104 | </structure>
105 | <section_number>18.2-186</section_number>
106 | <catch_line>False statements to obtain property or credit.</catch_line>
107 | <order_by>00000000009104318.2</order_by>
108 | <text>
109 | <section prefix="1">
110 | Notwithstanding § 18.2-186:
111 |
112 | <section prefix="A">A person shall be guilty of a Class 1 misdemeanor if he makes,
113 | causes to be made or conspires to make directly, indirectly or through an agency, any
114 | materially false statement in writing, knowing it to be false and intending that it be
115 | relied upon, concerning the financial condition or means or ability to pay of himself,
116 | or of any other person for whom he is acting, or any firm or corporation in which he is
117 | interested or for which he is acting, for the purpose of procuring, for his own benefit
118 | or for the benefit of such person, firm or corporation, the delivery of personal
119 | property, the payment of cash, the making of a loan or credit, the extension of a
120 | credit, the discount of an account receivable, or the making, acceptance, discount, sale
121 | or endorsement of a bill of exchange or promissory note.</section>
122 |
123 | <section prefix="B">Any person who knows that a false statement has been made in writing
124 | concerning the financial condition or ability to pay of himself or of any person for
125 | whom he is acting, or any firm or corporation in which he is interested or for which he
126 | is acting and who, with intent to defraud, procures, upon the faith thereof.
127 |
128 | <section prefix="i" type="table">
129 | +------------------+--------------------+
130 | | PERSON | STATEMENT |
131 | +------------------+--------------------+
132 | | any | false |
133 | | no | true |
134 | +------------------+--------------------+
135 | </section>
136 |
137 | For his own benefit, or for the benefit of the person, firm or corporation in which he
138 | is interested or for which he is acting, any such delivery, payment, loan, credit,
139 | extension, discount making, acceptance, sale or endorsement, shall, if the value of the
140 | thing or the amount of the loan, credit or benefit obtained is $200 or more, be guilty
141 | of grand larceny or, if the value is less than $200, be guilty of petit
142 | larceny.</section>
143 |
144 | <section prefix="C">Venue for the trial of any person charged with an offense under this
145 | section may be in the county or city in which (i) any act was performed in furtherance
146 | of the offense, or (ii) the person charged with the offense resided at the time of the
147 | offense.</section>
148 |
149 | <section prefix="D">As used in this section, "in writing" shall include information
150 | transmitted by computer, facsimile, e-mail, Internet, or any other electronic medium,
151 | and shall not include information transmitted by any such medium by voice
152 | transmission.</section>
153 | </section>
154 | <section prefix="2">
155 | This law shall expire on July 1, 2014.
156 | </section>
157 | </text>
158 | <history>Code 1950, § 18.1-125; 1960, c. 358; 1975, cc. 14, 15.</history>
159 | <metadata>
160 | <repealed>y</repealed>
161 | <expiration>2014-07-01</expiration>
162 | </metadata>
163 | <tags>
164 | <tag>lying</tag>
165 | <tag>fraud</tag>
166 | <tag>theft</tag>
167 | </tags>
168 | </law>
169 |